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>
29f1047e87767be1acd2c32f4d36028d1d0014f4c0Eric Laurent#include <cutils/multiuser.h>
3065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/properties.h>
3165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IPCThreadState.h>
32f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov#include <binder/ActivityManager.h>
33f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov#include <binder/PermissionController.h>
34f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov#include <binder/IResultReceiver.h>
3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String16.h>
3665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/threads.h>
3765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioPolicyService.h"
3844deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten#include "ServiceUtilities.h"
3965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <hardware_legacy/power.h>
407c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent#include <media/AudioEffect.h>
41c84d9d235679a4d48245b316b7b2e4c0b19413e7Chih-Hung Hsieh#include <media/AudioParameter.h>
4265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4364760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h>
447394a4f358fa9908a9f0a7c954b65c399f4268e6Dima Zavin#include <system/audio_policy.h>
4561a4fac2e3ec271241e3a4f405d7357b7f6ca4c2Mikhail Naganov
46f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov#include <private/android_filesystem_config.h>
47f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android {
4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
508dad0e31c2366c501bd1d600261d0af35a6ca786Glenn Kastenstatic const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n";
518dad0e31c2366c501bd1d600261d0af35a6ca786Glenn Kastenstatic const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n";
5265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50;
5422ecc912a87099cff8cadc424cd12f85c118673fGlenn Kastenstatic const int kDumpLockSleepUs = 20000;
5565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
560ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentstatic const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds
575fa8c4bf81275d5e1f5ef71bc66fc22e3152eeb0Christer Fletcher
58f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatic const String16 sManageAudioPolicyPermission("android.permission.MANAGE_AUDIO_POLICY");
59fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
6065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
6165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::AudioPolicyService()
63dce54a1492c410ad0d93253b341fb33305337505Eric Laurent    : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL),
64bb6c9a05840d924b502ce0f1868fca4881ada1edEric Laurent      mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID)
6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
66f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent}
67f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent
68f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurentvoid AudioPolicyService::onFirstRef()
69f5ada6edcc83bb1b313abcd4c4fbdc4f7724f04dEric Laurent{
708b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    {
718b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        Mutex::Autolock _l(mLock);
72935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent
738b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        // start tone playback thread
748b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
758b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        // start audio commands thread
768b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
778b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        // start output activity command thread
788b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
79dce54a1492c410ad0d93253b341fb33305337505Eric Laurent
808b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        mAudioPolicyClient = new AudioPolicyClient(this);
818b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
828b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    }
83ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // load audio processing modules
848b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects();
858b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    {
868b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        Mutex::Autolock _l(mLock);
878b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        mAudioPolicyEffects = audioPolicyEffects;
888b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    }
89f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
90f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    mUidPolicy = new UidPolicy(this);
91f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    mUidPolicy->registerSelf();
9265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
9365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::~AudioPolicyService()
9565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
9665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mTonePlaybackThread->exit();
9765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAudioCommandThread->exit();
98657ff61389d7316f798d4abe03efac56fd528d91Eric Laurent    mOutputCommandThread->exit();
997c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
100f269b8e0e9ab950fc6652b9594b7a3431c81630cEric Laurent    destroyAudioPolicyManager(mAudioPolicyManager);
101dce54a1492c410ad0d93253b341fb33305337505Eric Laurent    delete mAudioPolicyClient;
102b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
103b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mNotificationClients.clear();
104ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    mAudioPolicyEffects.clear();
105f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
106f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    mUidPolicy->unregisterSelf();
107f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    mUidPolicy.clear();
108b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
109b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
110b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// A notification client is always registered by AudioSystem when the client process
111b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// connects to AudioPolicyService.
112b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& client)
113b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
114125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent    if (client == 0) {
115125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent        ALOGW("%s got NULL client", __FUNCTION__);
116125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent        return;
117125902529aed131abc00210c36dc9ff03d9e8120Eric Laurent    }
1180ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent    Mutex::Autolock _l(mNotificationClientsLock);
119b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
120b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    uid_t uid = IPCThreadState::self()->getCallingUid();
121b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    if (mNotificationClients.indexOfKey(uid) < 0) {
122b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        sp<NotificationClient> notificationClient = new NotificationClient(this,
123b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                                                                           client,
124b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                                                                           uid);
125b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        ALOGV("registerClient() client %p, uid %d", client.get(), uid);
126b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
127b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        mNotificationClients.add(uid, notificationClient);
128b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
129f888020c6e2735624f2b2a30e72aca24e17b8b4dMarco Nelissen        sp<IBinder> binder = IInterface::asBinder(client);
130b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        binder->linkToDeath(notificationClient);
131b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    }
132b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
133b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
134e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurentvoid AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled)
135e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent{
136e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    Mutex::Autolock _l(mNotificationClientsLock);
137e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent
138e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    uid_t uid = IPCThreadState::self()->getCallingUid();
139e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    if (mNotificationClients.indexOfKey(uid) < 0) {
140e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent        return;
141e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    }
142e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled);
143e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent}
144e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent
145b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent// removeNotificationClient() is called when the client process dies.
146b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::removeNotificationClient(uid_t uid)
147b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
1480ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent    {
1490ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent        Mutex::Autolock _l(mNotificationClientsLock);
1500ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent        mNotificationClients.removeItem(uid);
1510ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent    }
1520ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent    {
1530ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent        Mutex::Autolock _l(mLock);
154b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        if (mAudioPolicyManager) {
15510b7123bd6ce29fe756422aeedc5cfe469c4309fEric Laurent            // called from binder death notification: no need to clear caller identity
1568c7e6dac6f5eb38cef627dab92eac8b38513450cEric Laurent            mAudioPolicyManager->releaseResourcesForUid(uid);
157b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        }
1580ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent    }
159b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
160b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
161b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::onAudioPortListUpdate()
162b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
163b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mOutputCommandThread->updateAudioPortListCommand();
164b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
165b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
166b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::doOnAudioPortListUpdate()
167b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
1680ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent    Mutex::Autolock _l(mNotificationClientsLock);
169b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    for (size_t i = 0; i < mNotificationClients.size(); i++) {
170b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        mNotificationClients.valueAt(i)->onAudioPortListUpdate();
171b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    }
172b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
173b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
174b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::onAudioPatchListUpdate()
175b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
176b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    mOutputCommandThread->updateAudioPatchListCommand();
17765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
17865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
179b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::doOnAudioPatchListUpdate()
180b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
1810ebd5f95b68a3a5c9e5509f21938c9e51e74d71bEric Laurent    Mutex::Autolock _l(mNotificationClientsLock);
182b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    for (size_t i = 0; i < mNotificationClients.size(); i++) {
183b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        mNotificationClients.valueAt(i)->onAudioPatchListUpdate();
184b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    }
185b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
186b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
187e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehvoid AudioPolicyService::onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
188de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{
189de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    ALOGV("AudioPolicyService::onDynamicPolicyMixStateUpdate(%s, %d)",
190de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi            regId.string(), state);
191de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    mOutputCommandThread->dynamicPolicyMixStateUpdateCommand(regId, state);
192de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi}
193de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi
194e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsiehvoid AudioPolicyService::doOnDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
195de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{
196de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    Mutex::Autolock _l(mNotificationClientsLock);
197de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    for (size_t i = 0; i < mNotificationClients.size(); i++) {
198de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi        mNotificationClients.valueAt(i)->onDynamicPolicyMixStateUpdate(regId, state);
199de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    }
200de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi}
201de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi
202ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivivoid AudioPolicyService::onRecordingConfigurationUpdate(int event,
203ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi        const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig,
2048c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle)
2052f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{
206ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi    mOutputCommandThread->recordingConfigurationUpdateCommand(event, clientInfo,
2078c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi            clientConfig, deviceConfig, patchHandle);
2082f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi}
2092f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
210ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivivoid AudioPolicyService::doOnRecordingConfigurationUpdate(int event,
211ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi        const record_client_info_t *clientInfo, const audio_config_base_t *clientConfig,
2128c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        const audio_config_base_t *deviceConfig, audio_patch_handle_t patchHandle)
2132f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{
2142f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    Mutex::Autolock _l(mNotificationClientsLock);
2152f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    for (size_t i = 0; i < mNotificationClients.size(); i++) {
216ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi        mNotificationClients.valueAt(i)->onRecordingConfigurationUpdate(event, clientInfo,
2178c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                clientConfig, deviceConfig, patchHandle);
2182f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    }
2192f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi}
2202f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
2212f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivistatus_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch,
2222f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                                                audio_patch_handle_t *handle,
2232f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                                                int delayMs)
2242f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{
2252f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs);
2262f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi}
2272f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
2282f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivistatus_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle,
2292f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                                                 int delayMs)
2302f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{
2312f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs);
2322f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi}
2332f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
234e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config,
235e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                                                      int delayMs)
236e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent{
237e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs);
238e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent}
239e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent
240b52c152d553556b2d227ffc943489de0c60b4b02Eric LaurentAudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service,
241b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                                                     const sp<IAudioPolicyServiceClient>& client,
242b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                                                     uid_t uid)
243e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    : mService(service), mUid(uid), mAudioPolicyServiceClient(client),
244e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent      mAudioPortCallbacksEnabled(false)
245b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
246b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
247b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
248b52c152d553556b2d227ffc943489de0c60b4b02Eric LaurentAudioPolicyService::NotificationClient::~NotificationClient()
249b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
250b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
251b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
252b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who __unused)
253b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
254b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    sp<NotificationClient> keep(this);
255b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    sp<AudioPolicyService> service = mService.promote();
256b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    if (service != 0) {
257b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        service->removeNotificationClient(mUid);
258b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    }
259b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
260b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
261b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::NotificationClient::onAudioPortListUpdate()
262b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
263e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
264b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        mAudioPolicyServiceClient->onAudioPortListUpdate();
265b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    }
266b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
267b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
268b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::NotificationClient::onAudioPatchListUpdate()
269b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
270e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
271b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent        mAudioPolicyServiceClient->onAudioPatchListUpdate();
272b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    }
273b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
27457dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent
275de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivivoid AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate(
276e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh        const String8& regId, int32_t state)
277de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{
278f1047e87767be1acd2c32f4d36028d1d0014f4c0Eric Laurent    if (mAudioPolicyServiceClient != 0 && multiuser_get_app_id(mUid) < AID_APP_START) {
2792f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(regId, state);
2802f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    }
2812f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi}
2822f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
2832f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivivoid AudioPolicyService::NotificationClient::onRecordingConfigurationUpdate(
284ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi        int event, const record_client_info_t *clientInfo,
2858c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
2868c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        audio_patch_handle_t patchHandle)
2872f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{
288f1047e87767be1acd2c32f4d36028d1d0014f4c0Eric Laurent    if (mAudioPolicyServiceClient != 0 && multiuser_get_app_id(mUid) < AID_APP_START) {
289ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi        mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, clientInfo,
2908c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                clientConfig, deviceConfig, patchHandle);
291de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    }
292de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi}
293de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi
294e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurentvoid AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool enabled)
295e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent{
296e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent    mAudioPortCallbacksEnabled = enabled;
297e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent}
298e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent
299e8726fea8a53bf3474aa3c6deaf2f6c1f565e694Eric Laurent
30065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::binderDied(const wp<IBinder>& who) {
301411e447c4b90298f5ff635429c53f94fbce4fff9Glenn Kasten    ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(),
302de070137f11d346fba77605bd76a44c040a618fcEric Laurent            IPCThreadState::self()->getCallingPid());
30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex)
30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = false;
30865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < kDumpLockRetries; ++i) {
30965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mutex.tryLock() == NO_ERROR) {
31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            locked = true;
31165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
31265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
31322ecc912a87099cff8cadc424cd12f85c118673fGlenn Kasten        usleep(kDumpLockSleepUs);
31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
31565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return locked;
31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::dumpInternals(int fd)
31965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
32065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
32165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
32265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
32365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
324dce54a1492c410ad0d93253b341fb33305337505Eric Laurent    snprintf(buffer, SIZE, "AudioPolicyManager: %p\n", mAudioPolicyManager);
32565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
32665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
32765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
32865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
33065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
33265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
33365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
33465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
335f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovvoid AudioPolicyService::setRecordSilenced(uid_t uid, bool silenced)
336f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov{
337eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    {
338eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        Mutex::Autolock _l(mLock);
339eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        if (mAudioPolicyManager) {
34010b7123bd6ce29fe756422aeedc5cfe469c4309fEric Laurent            AutoCallerClear acc;
341eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov            mAudioPolicyManager->setRecordSilenced(uid, silenced);
342eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        }
343eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    }
344eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
345eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (af) {
346eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        af->setRecordSilenced(uid, silenced);
347eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    }
348f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
349f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
3500f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatus_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused)
35165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
35244deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten    if (!dumpAllowed()) {
35365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpPermissionDenial(fd);
35465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
35565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool locked = tryLock(mLock);
35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!locked) {
35765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            String8 result(kDeadlockedString);
35865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
35965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
36065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
36165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpInternals(fd);
3629d1f02d74fd395ec4de6861147da289423f0ab6fGlenn Kasten        if (mAudioCommandThread != 0) {
36365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mAudioCommandThread->dump(fd);
36465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
3659d1f02d74fd395ec4de6861147da289423f0ab6fGlenn Kasten        if (mTonePlaybackThread != 0) {
36665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mTonePlaybackThread->dump(fd);
36765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
36865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
369dce54a1492c410ad0d93253b341fb33305337505Eric Laurent        if (mAudioPolicyManager) {
370dce54a1492c410ad0d93253b341fb33305337505Eric Laurent            mAudioPolicyManager->dump(fd);
371dce54a1492c410ad0d93253b341fb33305337505Eric Laurent        }
37265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (locked) mLock.unlock();
37465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
37565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
37665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
37765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::dumpPermissionDenial(int fd)
37965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
38065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
38165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
38265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
38365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Permission Denial: "
38465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "can't dump AudioPolicyService from pid=%d, uid=%d\n",
38565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IPCThreadState::self()->getCallingPid(),
38665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IPCThreadState::self()->getCallingUid());
38765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
38865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
38965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
39065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
39165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::onTransact(
393f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
394f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    switch (code) {
395f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        case SHELL_COMMAND_TRANSACTION: {
396f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            int in = data.readFileDescriptor();
397f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            int out = data.readFileDescriptor();
398f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            int err = data.readFileDescriptor();
399f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            int argc = data.readInt32();
400f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            Vector<String16> args;
401f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            for (int i = 0; i < argc && data.dataAvail() > 0; i++) {
402f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov               args.add(data.readString16());
403f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            }
404f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            sp<IBinder> unusedCallback;
405f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            sp<IResultReceiver> resultReceiver;
406f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            status_t status;
407f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            if ((status = data.readNullableStrongBinder(&unusedCallback)) != NO_ERROR) {
408f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                return status;
409f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            }
410f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            if ((status = data.readNullableStrongBinder(&resultReceiver)) != NO_ERROR) {
411f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                return status;
412f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            }
413f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            status = shellCommand(in, out, err, args);
414f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            if (resultReceiver != nullptr) {
415f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov                resultReceiver->send(status);
416f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            }
417f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            return NO_ERROR;
418f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        }
419f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
420f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
42165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnAudioPolicyService::onTransact(code, data, reply, flags);
42265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
42365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
424f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov// ------------------- Shell command implementation -------------------
425f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
426f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov// NOTE: This is a remote API - make sure all args are validated
427f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatus_t AudioPolicyService::shellCommand(int in, int out, int err, Vector<String16>& args) {
428f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    if (!checkCallingPermission(sManageAudioPolicyPermission, nullptr, nullptr)) {
429f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return PERMISSION_DENIED;
430f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
431f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    if (in == BAD_TYPE || out == BAD_TYPE || err == BAD_TYPE) {
432f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return BAD_VALUE;
433f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
434f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    if (args.size() == 3 && args[0] == String16("set-uid-state")) {
435f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return handleSetUidState(args, err);
436f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    } else if (args.size() == 2 && args[0] == String16("reset-uid-state")) {
437f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return handleResetUidState(args, err);
438f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    } else if (args.size() == 2 && args[0] == String16("get-uid-state")) {
439f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return handleGetUidState(args, out, err);
440f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    } else if (args.size() == 1 && args[0] == String16("help")) {
441f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        printHelp(out);
442f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return NO_ERROR;
443f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
444f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    printHelp(err);
445f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    return BAD_VALUE;
446f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
447f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
448f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatus_t AudioPolicyService::handleSetUidState(Vector<String16>& args, int err) {
449f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    PermissionController pc;
450f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    int uid = pc.getPackageUid(args[1], 0);
451f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    if (uid <= 0) {
452f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        ALOGE("Unknown package: '%s'", String8(args[1]).string());
453f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
454f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return BAD_VALUE;
455f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
456f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    bool active = false;
457f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    if (args[2] == String16("active")) {
458f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        active = true;
459f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    } else if ((args[2] != String16("idle"))) {
460f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
461f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return BAD_VALUE;
462f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
463f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    mUidPolicy->addOverrideUid(uid, active);
464f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    return NO_ERROR;
465f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
466f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
467f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatus_t AudioPolicyService::handleResetUidState(Vector<String16>& args, int err) {
468f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    PermissionController pc;
469f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    int uid = pc.getPackageUid(args[1], 0);
470f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    if (uid < 0) {
471f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        ALOGE("Unknown package: '%s'", String8(args[1]).string());
472f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
473f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return BAD_VALUE;
474f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
475f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    mUidPolicy->removeOverrideUid(uid);
476f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    return NO_ERROR;
477f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
478f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
479f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatus_t AudioPolicyService::handleGetUidState(Vector<String16>& args, int out, int err) {
480f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    PermissionController pc;
481f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    int uid = pc.getPackageUid(args[1], 0);
482f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    if (uid < 0) {
483f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        ALOGE("Unknown package: '%s'", String8(args[1]).string());
484f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
485f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return BAD_VALUE;
486f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
487f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    if (mUidPolicy->isUidActive(uid)) {
488f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return dprintf(out, "active\n");
489f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    } else {
490f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        return dprintf(out, "idle\n");
491f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
492f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
493f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
494f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovstatus_t AudioPolicyService::printHelp(int out) {
495f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    return dprintf(out, "Audio policy service commands:\n"
496f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        "  get-uid-state <PACKAGE> gets the uid state\n"
497f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        "  set-uid-state <PACKAGE> <active|idle> overrides the uid state\n"
498f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        "  reset-uid-state <PACKAGE> clears the uid state override\n"
499f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        "  help print this message\n");
500f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
501f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
502f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov// -----------  AudioPolicyService::UidPolicy implementation ----------
503f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
504f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovvoid AudioPolicyService::UidPolicy::registerSelf() {
505f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    ActivityManager am;
506f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    am.registerUidObserver(this, ActivityManager::UID_OBSERVER_GONE
507f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            | ActivityManager::UID_OBSERVER_IDLE
508f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            | ActivityManager::UID_OBSERVER_ACTIVE,
509f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            ActivityManager::PROCESS_STATE_UNKNOWN,
510f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov            String16("audioserver"));
511eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    status_t res = am.linkToDeath(this);
512eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (!res) {
513eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        Mutex::Autolock _l(mLock);
514eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        mObserverRegistered = true;
515eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    } else {
516eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        ALOGE("UidPolicy::registerSelf linkToDeath failed: %d", res);
517eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        am.unregisterUidObserver(this);
518eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    }
519f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
520f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
521f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovvoid AudioPolicyService::UidPolicy::unregisterSelf() {
522f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    ActivityManager am;
523eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    am.unlinkToDeath(this);
524f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    am.unregisterUidObserver(this);
525eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    Mutex::Autolock _l(mLock);
526eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    mObserverRegistered = false;
527f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
528f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
529eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::binderDied(__unused const wp<IBinder> &who) {
530eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    Mutex::Autolock _l(mLock);
531eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    mCachedUids.clear();
532eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    mObserverRegistered = false;
533f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
534f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
535eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovbool AudioPolicyService::UidPolicy::isUidActive(uid_t uid) {
536eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (isServiceUid(uid)) return true;
537eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    bool needToReregister = false;
538f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    {
539eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        Mutex::Autolock _l(mLock);
540eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        needToReregister = !mObserverRegistered;
541f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
542eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (needToReregister) {
543eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        // Looks like ActivityManager has died previously, attempt to re-register.
544eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        registerSelf();
545f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
546f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    {
547eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        Mutex::Autolock _l(mLock);
548eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        auto overrideIter = mOverrideUids.find(uid);
549eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        if (overrideIter != mOverrideUids.end()) {
550eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov            return overrideIter->second;
551f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        }
552eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        // In an absense of the ActivityManager, assume everything to be active.
553eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        if (!mObserverRegistered) return true;
554eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        auto cacheIter = mCachedUids.find(uid);
555eba668adbdee1ecfcf00fa9f9fc066c022cfddbaMikhail Naganov        if (cacheIter != mCachedUids.end()) {
556eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov            return cacheIter->second;
557f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov        }
558f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
559eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    ActivityManager am;
560eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    bool active = am.isUidActive(uid, String16("audioserver"));
561eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    {
562eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        Mutex::Autolock _l(mLock);
563eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        mCachedUids.insert(std::pair<uid_t, bool>(uid, active));
564eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    }
565eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    return active;
566f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
567f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
568eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::onUidActive(uid_t uid) {
569eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    updateUidCache(uid, true, true);
570f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
571f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
572eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::onUidGone(uid_t uid, __unused bool disabled) {
573eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    updateUidCache(uid, false, false);
574eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov}
575eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov
576eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) {
577eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    updateUidCache(uid, false, true);
578eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov}
579eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov
580eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovbool AudioPolicyService::UidPolicy::isServiceUid(uid_t uid) const {
581f1047e87767be1acd2c32f4d36028d1d0014f4c0Eric Laurent    return multiuser_get_app_id(uid) < AID_APP_START;
582eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov}
583eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov
584eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::notifyService(uid_t uid, bool active) {
585eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    sp<AudioPolicyService> service = mService.promote();
586eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (service != nullptr) {
587eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        service->setRecordSilenced(uid, !active);
588eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    }
589f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
590f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
591f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganovvoid AudioPolicyService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
592eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (isServiceUid(uid)) return;
593eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    bool wasOverridden = false, wasActive = false;
594f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    {
595eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        Mutex::Autolock _l(mLock);
596eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        updateUidLocked(&mOverrideUids, uid, active, insert, &wasOverridden, &wasActive);
597f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
598eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (!wasOverridden && insert) {
599eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        notifyService(uid, active);  // Started to override.
600eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    } else if (wasOverridden && !insert) {
601eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        notifyService(uid, isUidActive(uid));  // Override ceased, notify with ground truth.
602eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    } else if (wasActive != active) {
603eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        notifyService(uid, active);  // Override updated.
604f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov    }
605f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
606f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov
607eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::updateUidCache(uid_t uid, bool active, bool insert) {
608eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (isServiceUid(uid)) return;
609eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    bool wasActive = false;
610eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    {
611eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        Mutex::Autolock _l(mLock);
612eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        updateUidLocked(&mCachedUids, uid, active, insert, nullptr, &wasActive);
613eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        // Do not notify service if currently overridden.
614eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        if (mOverrideUids.find(uid) != mOverrideUids.end()) return;
615eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    }
616eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    bool nowActive = active && insert;
617eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (wasActive != nowActive) notifyService(uid, nowActive);
618eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov}
619eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov
620eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganovvoid AudioPolicyService::UidPolicy::updateUidLocked(std::unordered_map<uid_t, bool> *uids,
621eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        uid_t uid, bool active, bool insert, bool *wasThere, bool *wasActive) {
622eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    auto it = uids->find(uid);
623eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    if (it != uids->end()) {
624eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        if (wasThere != nullptr) *wasThere = true;
625eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        if (wasActive != nullptr) *wasActive = it->second;
626eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        if (insert) {
627eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov            it->second = active;
628eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        } else {
629eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov            uids->erase(it);
630eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        }
631eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    } else if (insert) {
632eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov        uids->insert(std::pair<uid_t, bool>(uid, active));
633eae73eb726c141056caf5a7ff95d45c3bcdd999fMikhail Naganov    }
634f4ddfefc8ba59a8486d91826154cc9447821409eSvet Ganov}
63565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
63665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// -----------  AudioPolicyService::AudioCommandThread implementation ----------
63765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
638bfb1b832079bbb9426f72f3863199a54aefd02daEric LaurentAudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name,
639bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                                                           const wp<AudioPolicyService>& service)
640bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    : Thread(false), mName(name), mService(service)
64165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
64265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mpToneGenerator = NULL;
64365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
64465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
64565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
64665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::AudioCommandThread::~AudioCommandThread()
64765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
648bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (!mAudioCommands.isEmpty()) {
64965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        release_wake_lock(mName.string());
65065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
65165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAudioCommands.clear();
652e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten    delete mpToneGenerator;
65365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
65465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
65565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::onFirstRef()
65665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
657bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    run(mName.string(), ANDROID_PRIORITY_AUDIO);
65865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
65965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
66065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioPolicyService::AudioCommandThread::threadLoop()
66165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
662d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent    nsecs_t waitTime = -1;
66365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
66465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLock.lock();
66565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!exitPending())
66665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
66759a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent        sp<AudioPolicyService> svc;
66859a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent        while (!mAudioCommands.isEmpty() && !exitPending()) {
66965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            nsecs_t curTime = systemTime();
67065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // commands are sorted by increasing time stamp: execute them from index 0 and up
67165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (mAudioCommands[0]->mTime <= curTime) {
6720ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                sp<AudioCommand> command = mAudioCommands[0];
67365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mAudioCommands.removeAt(0);
6740ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                mLastCommand = command;
67565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
67665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                switch (command->mCommand) {
67765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                case START_TONE: {
67865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mLock.unlock();
6790ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    ToneData *data = (ToneData *)command->mParam.get();
6803856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("AudioCommandThread() processing start tone %d on stream %d",
68165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            data->mType, data->mStream);
682e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten                    delete mpToneGenerator;
68365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mpToneGenerator = new ToneGenerator(data->mStream, 1.0);
68465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mpToneGenerator->startTone(data->mType);
68565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mLock.lock();
68665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }break;
68765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                case STOP_TONE: {
68865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mLock.unlock();
6893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("AudioCommandThread() processing stop tone");
69065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    if (mpToneGenerator != NULL) {
69165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        mpToneGenerator->stopTone();
69265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        delete mpToneGenerator;
69365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        mpToneGenerator = NULL;
69465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }
69565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mLock.lock();
69665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }break;
69765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                case SET_VOLUME: {
6980ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    VolumeData *data = (VolumeData *)command->mParam.get();
6993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("AudioCommandThread() processing set volume stream %d, \
700de070137f11d346fba77605bd76a44c040a618fcEric Laurent                            volume %f, output %d", data->mStream, data->mVolume, data->mIO);
701de070137f11d346fba77605bd76a44c040a618fcEric Laurent                    command->mStatus = AudioSystem::setStreamVolume(data->mStream,
702de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                                                    data->mVolume,
703de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                                                    data->mIO);
70465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }break;
70565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                case SET_PARAMETERS: {
7060ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    ParametersData *data = (ParametersData *)command->mParam.get();
707e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    ALOGV("AudioCommandThread() processing set parameters string %s, io %d",
708e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                            data->mKeyValuePairs.string(), data->mIO);
709e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
710e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    }break;
71165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                case SET_VOICE_VOLUME: {
7120ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
7133856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("AudioCommandThread() processing set voice volume volume %f",
714de070137f11d346fba77605bd76a44c040a618fcEric Laurent                            data->mVolume);
71565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
71665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }break;
717bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                case STOP_OUTPUT: {
7180ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    StopOutputData *data = (StopOutputData *)command->mParam.get();
719bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    ALOGV("AudioCommandThread() processing stop output %d",
720bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                            data->mIO);
72159a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent                    svc = mService.promote();
722bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    if (svc == 0) {
723bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                        break;
724bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    }
725bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    mLock.unlock();
726bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    svc->doStopOutput(data->mIO, data->mStream, data->mSession);
727bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    mLock.lock();
728bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    }break;
729bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                case RELEASE_OUTPUT: {
7300ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get();
731bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    ALOGV("AudioCommandThread() processing release output %d",
732bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                            data->mIO);
73359a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent                    svc = mService.promote();
734bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    if (svc == 0) {
735bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                        break;
736bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    }
737bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    mLock.unlock();
738e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                    svc->doReleaseOutput(data->mIO, data->mStream, data->mSession);
739bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    mLock.lock();
740bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    }break;
741951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                case CREATE_AUDIO_PATCH: {
742951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get();
743951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    ALOGV("AudioCommandThread() processing create audio patch");
744951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
745951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    if (af == 0) {
746951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                        command->mStatus = PERMISSION_DENIED;
747951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    } else {
748951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                        command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle);
749951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    }
750951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    } break;
751951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                case RELEASE_AUDIO_PATCH: {
752951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    ReleaseAudioPatchData *data = (ReleaseAudioPatchData *)command->mParam.get();
753951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    ALOGV("AudioCommandThread() processing release audio patch");
754951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
755951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    if (af == 0) {
756951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                        command->mStatus = PERMISSION_DENIED;
757951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    } else {
758951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                        command->mStatus = af->releaseAudioPatch(data->mHandle);
759951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    }
760951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                    } break;
761b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                case UPDATE_AUDIOPORT_LIST: {
762b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    ALOGV("AudioCommandThread() processing update audio port list");
76359a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent                    svc = mService.promote();
764b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    if (svc == 0) {
765b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                        break;
766b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    }
767b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    mLock.unlock();
768b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    svc->doOnAudioPortListUpdate();
769b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    mLock.lock();
770b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    }break;
771b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                case UPDATE_AUDIOPATCH_LIST: {
772b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    ALOGV("AudioCommandThread() processing update audio patch list");
77359a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent                    svc = mService.promote();
774b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    if (svc == 0) {
775b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                        break;
776b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    }
777b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    mLock.unlock();
778b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    svc->doOnAudioPatchListUpdate();
779b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    mLock.lock();
780b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent                    }break;
781e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                case SET_AUDIOPORT_CONFIG: {
782e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                    SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get();
783e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                    ALOGV("AudioCommandThread() processing set port config");
784e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
785e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                    if (af == 0) {
786e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                        command->mStatus = PERMISSION_DENIED;
787e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                    } else {
788e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                        command->mStatus = af->setAudioPortConfig(&data->mConfig);
789e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                    }
790e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                    } break;
791de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                case DYN_POLICY_MIX_STATE_UPDATE: {
792de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    DynPolicyMixStateUpdateData *data =
793de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                            (DynPolicyMixStateUpdateData *)command->mParam.get();
794de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    ALOGV("AudioCommandThread() processing dyn policy mix state update %s %d",
795de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                            data->mRegId.string(), data->mState);
796de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    svc = mService.promote();
797de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    if (svc == 0) {
798de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                        break;
799de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    }
800de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    mLock.unlock();
801de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    svc->doOnDynamicPolicyMixStateUpdate(data->mRegId, data->mState);
802de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    mLock.lock();
803de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi                    } break;
8042f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                case RECORDING_CONFIGURATION_UPDATE: {
8052f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    RecordingConfigurationUpdateData *data =
8062f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                            (RecordingConfigurationUpdateData *)command->mParam.get();
8072f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    ALOGV("AudioCommandThread() processing recording configuration update");
8082f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    svc = mService.promote();
8092f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    if (svc == 0) {
8102f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                        break;
8112f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    }
8122f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    mLock.unlock();
813ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi                    svc->doOnRecordingConfigurationUpdate(data->mEvent, &data->mClientInfo,
814ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi                            &data->mClientConfig, &data->mDeviceConfig,
8158c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi                            data->mPatchHandle);
8162f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    mLock.lock();
8172f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi                    } break;
81865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                default:
8195ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                    ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
82065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
8210ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                {
8220ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    Mutex::Autolock _l(command->mLock);
8230ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    if (command->mWaitStatus) {
8240ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                        command->mWaitStatus = false;
8250ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                        command->mCond.signal();
8260ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                    }
8270ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent                }
828d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent                waitTime = -1;
829a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang                // release mLock before releasing strong reference on the service as
830a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang                // AudioPolicyService destructor calls AudioCommandThread::exit() which
831a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang                // acquires mLock.
832a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang                mLock.unlock();
833a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang                svc.clear();
834a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang                mLock.lock();
83565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
83665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                waitTime = mAudioCommands[0]->mTime - curTime;
83765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                break;
83865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
83965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
840a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang
841a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang        // release delayed commands wake lock if the queue is empty
842a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang        if (mAudioCommands.isEmpty()) {
84305f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia            release_wake_lock(mName.string());
844a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang        }
845a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang
846a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang        // At this stage we have either an empty command queue or the first command in the queue
847a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang        // has a finite delay. So unless we are exiting it is safe to wait.
848a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang        if (!exitPending()) {
84959a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent            ALOGV("AudioCommandThread() going to sleep");
850d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent            if (waitTime == -1) {
851d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent                mWaitWorkCV.wait(mLock);
852d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent            } else {
853d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent                mWaitWorkCV.waitRelative(mLock, waitTime);
854d7eda8d0127fabf2d63b0890043da40e2a9e366cEric Laurent            }
85559a8923027d2d6a155c0fa434ae65559318da4b6Eric Laurent        }
85665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
85705f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia    // release delayed commands wake lock before quitting
85805f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia    if (!mAudioCommands.isEmpty()) {
85905f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia        release_wake_lock(mName.string());
86005f2fdc1070c1c07af9e21760d4d2e06bebde55aRicardo Garcia    }
86165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLock.unlock();
86265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return false;
86365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
86465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
86565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::AudioCommandThread::dump(int fd)
86665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
86765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
86865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
86965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
87065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
87165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
87265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
87365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
87465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
87565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = tryLock(mLock);
87665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!locked) {
87765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        String8 result2(kCmdDeadlockedString);
87865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        write(fd, result2.string(), result2.size());
87965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
88065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
88165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "- Commands:\n");
88265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result = String8(buffer);
88365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("   Command Time        Wait pParam\n");
8848d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i < mAudioCommands.size(); i++) {
88565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mAudioCommands[i]->dump(buffer, SIZE);
88665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        result.append(buffer);
88765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
88865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("  Last Command\n");
8890ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    if (mLastCommand != 0) {
8900ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        mLastCommand->dump(buffer, SIZE);
8910ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        result.append(buffer);
8920ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    } else {
8930ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        result.append("     none\n");
8940ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    }
89565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
89665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
89765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
89865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (locked) mLock.unlock();
89965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
90065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
90165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
90265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
9033d2f877c1cb4e4ae4ddde7f57f4353de9341f11bGlenn Kastenvoid AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::tone_type type,
9043d2f877c1cb4e4ae4ddde7f57f4353de9341f11bGlenn Kasten        audio_stream_type_t stream)
90565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
9060ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<AudioCommand> command = new AudioCommand();
90765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mCommand = START_TONE;
9080ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<ToneData> data = new ToneData();
90965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mType = type;
91065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mStream = stream;
91148412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh    command->mParam = data;
9123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
9130ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sendCommand(command);
91465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
91565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
91665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::stopToneCommand()
91765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
9180ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<AudioCommand> command = new AudioCommand();
91965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mCommand = STOP_TONE;
9203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread() adding tone stop");
9210ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sendCommand(command);
92265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
92365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
924fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenstatus_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream,
925de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                                               float volume,
92672ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten                                                               audio_io_handle_t output,
927de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                                               int delayMs)
92865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
9290ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<AudioCommand> command = new AudioCommand();
93065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mCommand = SET_VOLUME;
9310ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<VolumeData> data = new VolumeData();
93265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mStream = stream;
93365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mVolume = volume;
93465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mIO = output;
93565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mParam = data;
9360ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    command->mWaitStatus = true;
9373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d",
938de070137f11d346fba77605bd76a44c040a618fcEric Laurent            stream, volume, output);
9390ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    return sendCommand(command, delayMs);
94065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
94165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
94272ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle,
943fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                                                   const char *keyValuePairs,
944de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                                                   int delayMs)
94565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
9460ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<AudioCommand> command = new AudioCommand();
94765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mCommand = SET_PARAMETERS;
9480ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<ParametersData> data = new ParametersData();
94965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mIO = ioHandle;
950fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    data->mKeyValuePairs = String8(keyValuePairs);
95165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mParam = data;
9520ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    command->mWaitStatus = true;
9533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d",
954fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin            keyValuePairs, ioHandle, delayMs);
9550ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    return sendCommand(command, delayMs);
95665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
95765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
95865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
95965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
9600ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<AudioCommand> command = new AudioCommand();
96165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mCommand = SET_VOICE_VOLUME;
9620ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<VoiceVolumeData> data = new VoiceVolumeData();
96365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mVolume = volume;
96465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mParam = data;
9650ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    command->mWaitStatus = true;
9663856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread() adding set voice volume volume %f", volume);
9670ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    return sendCommand(command, delayMs);
96865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
96965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
970bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output,
971bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                                                               audio_stream_type_t stream,
972e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                                               audio_session_t session)
973bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{
9740ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<AudioCommand> command = new AudioCommand();
975bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    command->mCommand = STOP_OUTPUT;
9760ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<StopOutputData> data = new StopOutputData();
977bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    data->mIO = output;
978bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    data->mStream = stream;
979bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    data->mSession = session;
98048412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh    command->mParam = data;
981bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    ALOGV("AudioCommandThread() adding stop output %d", output);
9820ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sendCommand(command);
983bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent}
984bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
985e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurentvoid AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output,
986e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                                                  audio_stream_type_t stream,
987e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent                                                                  audio_session_t session)
988bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{
9890ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<AudioCommand> command = new AudioCommand();
990bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    command->mCommand = RELEASE_OUTPUT;
9910ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sp<ReleaseOutputData> data = new ReleaseOutputData();
992bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    data->mIO = output;
993e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    data->mStream = stream;
994e83b55dc29ca16092ba02f36f55fa6e0e37fd78cEric Laurent    data->mSession = session;
99548412dc92c4cc92a3f4821616e12290f5eeabd07Jesper Tragardh    command->mParam = data;
996bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    ALOGV("AudioCommandThread() adding release output %d", output);
9970ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    sendCommand(command);
9980ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent}
9990ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent
1000951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand(
1001951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                                                const struct audio_patch *patch,
1002951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                                                audio_patch_handle_t *handle,
1003951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                                                int delayMs)
1004951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent{
1005951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    status_t status = NO_ERROR;
1006951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent
1007951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    sp<AudioCommand> command = new AudioCommand();
1008951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    command->mCommand = CREATE_AUDIO_PATCH;
1009951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    CreateAudioPatchData *data = new CreateAudioPatchData();
1010951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    data->mPatch = *patch;
1011951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    data->mHandle = *handle;
1012951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    command->mParam = data;
1013951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    command->mWaitStatus = true;
1014951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    ALOGV("AudioCommandThread() adding create patch delay %d", delayMs);
1015951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    status = sendCommand(command, delayMs);
1016951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    if (status == NO_ERROR) {
1017951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent        *handle = data->mHandle;
1018951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    }
1019951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    return status;
1020951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent}
1021951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent
1022951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle,
1023951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent                                                 int delayMs)
1024951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent{
1025951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    sp<AudioCommand> command = new AudioCommand();
1026951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    command->mCommand = RELEASE_AUDIO_PATCH;
1027951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    ReleaseAudioPatchData *data = new ReleaseAudioPatchData();
1028951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    data->mHandle = handle;
1029951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    command->mParam = data;
1030951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    command->mWaitStatus = true;
1031951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    ALOGV("AudioCommandThread() adding release patch delay %d", delayMs);
1032951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent    return sendCommand(command, delayMs);
1033951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent}
1034951f455566775e5f01e67c5ee26863d7d19209d7Eric Laurent
1035b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::AudioCommandThread::updateAudioPortListCommand()
1036b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
1037b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    sp<AudioCommand> command = new AudioCommand();
1038b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    command->mCommand = UPDATE_AUDIOPORT_LIST;
1039b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    ALOGV("AudioCommandThread() adding update audio port list");
1040b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    sendCommand(command);
1041b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
1042b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
1043b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurentvoid AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand()
1044b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent{
1045b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    sp<AudioCommand>command = new AudioCommand();
1046b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    command->mCommand = UPDATE_AUDIOPATCH_LIST;
1047b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    ALOGV("AudioCommandThread() adding update audio patch list");
1048b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent    sendCommand(command);
1049b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent}
1050b52c152d553556b2d227ffc943489de0c60b4b02Eric Laurent
1051e1715a465a29db625da9d0ea365edf371e39e201Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand(
1052e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent                                            const struct audio_port_config *config, int delayMs)
1053e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent{
1054e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    sp<AudioCommand> command = new AudioCommand();
1055e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    command->mCommand = SET_AUDIOPORT_CONFIG;
1056e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    SetAudioPortConfigData *data = new SetAudioPortConfigData();
1057e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    data->mConfig = *config;
1058e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    command->mParam = data;
1059e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    command->mWaitStatus = true;
1060e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    ALOGV("AudioCommandThread() adding set port config delay %d", delayMs);
1061e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent    return sendCommand(command, delayMs);
1062e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent}
1063e1715a465a29db625da9d0ea365edf371e39e201Eric Laurent
1064de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivivoid AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand(
1065e964d4e421e2d1ca937227a580c0c837091a11e3Chih-Hung Hsieh        const String8& regId, int32_t state)
1066de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi{
1067de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    sp<AudioCommand> command = new AudioCommand();
1068de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    command->mCommand = DYN_POLICY_MIX_STATE_UPDATE;
1069de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    DynPolicyMixStateUpdateData *data = new DynPolicyMixStateUpdateData();
1070de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    data->mRegId = regId;
1071de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    data->mState = state;
1072de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    command->mParam = data;
1073de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    ALOGV("AudioCommandThread() sending dynamic policy mix (id=%s) state update to %d",
1074de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi            regId.string(), state);
1075de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi    sendCommand(command);
1076de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi}
1077de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi
10782f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivivoid AudioPolicyService::AudioCommandThread::recordingConfigurationUpdateCommand(
1079ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi        int event, const record_client_info_t *clientInfo,
10808c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
10818c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi        audio_patch_handle_t patchHandle)
10822f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi{
10832f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    sp<AudioCommand>command = new AudioCommand();
10842f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    command->mCommand = RECORDING_CONFIGURATION_UPDATE;
10852f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    RecordingConfigurationUpdateData *data = new RecordingConfigurationUpdateData();
10862f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    data->mEvent = event;
1087ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi    data->mClientInfo = *clientInfo;
10887281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi    data->mClientConfig = *clientConfig;
10897281aa9810b33eff47b00104db26c97c77931611Jean-Michel Trivi    data->mDeviceConfig = *deviceConfig;
10908c7cf3b7d0d7bccb9affbc34ae2ab2d6b332f972Jean-Michel Trivi    data->mPatchHandle = patchHandle;
10912f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    command->mParam = data;
1092ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi    ALOGV("AudioCommandThread() adding recording configuration update event %d, source %d uid %u",
1093ac4e42982d4537732b30e71c9a00ba0077944984Jean-Michel Trivi            event, clientInfo->source, clientInfo->uid);
10942f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi    sendCommand(command);
10952f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi}
10962f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
10970ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentstatus_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
10980ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent{
10990ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    {
11000ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        Mutex::Autolock _l(mLock);
11010ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        insertCommand_l(command, delayMs);
11020ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        mWaitWorkCV.signal();
11030ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    }
11040ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    Mutex::Autolock _l(command->mLock);
11050ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    while (command->mWaitStatus) {
11060ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs);
11070ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) {
11080ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent            command->mStatus = TIMED_OUT;
11090ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent            command->mWaitStatus = false;
11100ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        }
11110ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    }
11120ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    return command->mStatus;
1113bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent}
1114bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
111565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// insertCommand_l() must be called with mLock held
11160ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurentvoid AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs)
111765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
11188d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    ssize_t i;  // not size_t because i will count down to -1
11190ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent    Vector < sp<AudioCommand> > removedCommands;
112065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mTime = systemTime() + milliseconds(delayMs);
112165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
112265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // acquire wake lock to make sure delayed commands are processed
1123bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (mAudioCommands.isEmpty()) {
112465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string());
112565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
112665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
112765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check same pending commands with later time stamps and eliminate them
11285ff158fd499f581bdc1c3e91bbc03ce15eeeb77cIvan Lozano    for (i = (ssize_t)mAudioCommands.size()-1; i >= 0; i--) {
11290ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent        sp<AudioCommand> command2 = mAudioCommands[i];
113065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
113165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (command2->mTime <= command->mTime) break;
1132e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent
1133e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent        // create audio patch or release audio patch commands are equivalent
1134e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent        // with regard to filtering
1135e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent        if ((command->mCommand == CREATE_AUDIO_PATCH) ||
1136e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent                (command->mCommand == RELEASE_AUDIO_PATCH)) {
1137e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            if ((command2->mCommand != CREATE_AUDIO_PATCH) &&
1138e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent                    (command2->mCommand != RELEASE_AUDIO_PATCH)) {
1139e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent                continue;
1140e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            }
1141e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent        } else if (command2->mCommand != command->mCommand) continue;
114265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
114365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        switch (command->mCommand) {
114465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case SET_PARAMETERS: {
11450ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent            ParametersData *data = (ParametersData *)command->mParam.get();
11460ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent            ParametersData *data2 = (ParametersData *)command2->mParam.get();
114765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (data->mIO != data2->mIO) break;
11483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Comparing parameter command %s to new command %s",
1149de070137f11d346fba77605bd76a44c040a618fcEric Laurent                    data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
115065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            AudioParameter param = AudioParameter(data->mKeyValuePairs);
115165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
115265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            for (size_t j = 0; j < param.size(); j++) {
1153e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                String8 key;
1154e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                String8 value;
1155e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                param.getAt(j, key, value);
1156e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                for (size_t k = 0; k < param2.size(); k++) {
1157e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    String8 key2;
1158e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    String8 value2;
1159e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    param2.getAt(k, key2, value2);
1160e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    if (key2 == key) {
1161e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                        param2.remove(key2);
1162e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                        ALOGV("Filtering out parameter %s", key2.string());
1163e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                        break;
1164e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    }
1165e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                }
116665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
116765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // if all keys have been filtered out, remove the command.
116865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // otherwise, update the key value pairs
116965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (param2.size() == 0) {
117065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                removedCommands.add(command2);
117165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
117265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                data2->mKeyValuePairs = param2.toString();
117365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
117421e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            command->mTime = command2->mTime;
117521e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            // force delayMs to non 0 so that code below does not request to wait for
117621e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            // command status as the command is now delayed
117721e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            delayMs = 1;
117865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } break;
117965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
118065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case SET_VOLUME: {
11810ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent            VolumeData *data = (VolumeData *)command->mParam.get();
11820ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent            VolumeData *data2 = (VolumeData *)command2->mParam.get();
118365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (data->mIO != data2->mIO) break;
118465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (data->mStream != data2->mStream) break;
11853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Filtering out volume command on output %d for stream %d",
1186de070137f11d346fba77605bd76a44c040a618fcEric Laurent                    data->mIO, data->mStream);
118765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            removedCommands.add(command2);
118821e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            command->mTime = command2->mTime;
118921e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            // force delayMs to non 0 so that code below does not request to wait for
119021e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            // command status as the command is now delayed
119121e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            delayMs = 1;
119265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } break;
1193e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent
1194baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent        case SET_VOICE_VOLUME: {
1195baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent            VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
1196baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent            VoiceVolumeData *data2 = (VoiceVolumeData *)command2->mParam.get();
1197baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent            ALOGV("Filtering out voice volume command value %f replaced by %f",
1198baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent                  data2->mVolume, data->mVolume);
1199baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent            removedCommands.add(command2);
1200baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent            command->mTime = command2->mTime;
1201baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent            // force delayMs to non 0 so that code below does not request to wait for
1202baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent            // command status as the command is now delayed
1203baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent            delayMs = 1;
1204baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent        } break;
1205baf35feefcd14c13a6bf5ff5b651d9f22c2c3de0Eric Laurent
1206e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent        case CREATE_AUDIO_PATCH:
1207e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent        case RELEASE_AUDIO_PATCH: {
1208e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            audio_patch_handle_t handle;
1209a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George            struct audio_patch patch;
1210e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            if (command->mCommand == CREATE_AUDIO_PATCH) {
1211e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent                handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle;
1212a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch;
1213e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            } else {
1214e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent                handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle;
1215e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            }
1216e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            audio_patch_handle_t handle2;
1217a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George            struct audio_patch patch2;
1218e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            if (command2->mCommand == CREATE_AUDIO_PATCH) {
1219e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent                handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle;
1220a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                patch2 = ((CreateAudioPatchData *)command2->mParam.get())->mPatch;
1221e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            } else {
1222e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent                handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle;
1223f60b6b6c776a762827874f6f635c0577359a7ee4Glenn Kasten                memset(&patch2, 0, sizeof(patch2));
1224e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            }
1225e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            if (handle != handle2) break;
1226a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George            /* Filter CREATE_AUDIO_PATCH commands only when they are issued for
1227a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George               same output. */
1228a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George            if( (command->mCommand == CREATE_AUDIO_PATCH) &&
1229a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                (command2->mCommand == CREATE_AUDIO_PATCH) ) {
1230a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                bool isOutputDiff = false;
1231a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                if (patch.num_sources == patch2.num_sources) {
1232a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                    for (unsigned count = 0; count < patch.num_sources; count++) {
1233a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                        if (patch.sources[count].id != patch2.sources[count].id) {
1234a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                            isOutputDiff = true;
1235a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                            break;
1236a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                        }
1237a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                    }
1238a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                    if (isOutputDiff)
1239a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                       break;
1240a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George                }
1241a2d4a6dac432f0c4f543d79b9a63c55ae91f81d6Haynes Mathew George            }
1242e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            ALOGV("Filtering out %s audio patch command for handle %d",
1243e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent                  (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle);
1244e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            removedCommands.add(command2);
1245e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            command->mTime = command2->mTime;
1246e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            // force delayMs to non 0 so that code below does not request to wait for
1247e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            // command status as the command is now delayed
1248e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent            delayMs = 1;
1249e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent        } break;
1250e45b48aba115f4daf4a4aad31b6a95df9b79f463Eric Laurent
1251de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi        case DYN_POLICY_MIX_STATE_UPDATE: {
1252de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi
1253de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi        } break;
1254de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi
12552f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        case RECORDING_CONFIGURATION_UPDATE: {
12562f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
12572f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi        } break;
12582f4fe9f7df8f22c6bc8745407d19df73128810ecJean-Michel Trivi
125965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case START_TONE:
126065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case STOP_TONE:
126165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        default:
126265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
126365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
126465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
126565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
126665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // remove filtered commands
126765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t j = 0; j < removedCommands.size(); j++) {
126865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // removed commands always have time stamps greater than current command
126965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
12700ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent            if (mAudioCommands[k].get() == removedCommands[j].get()) {
12713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
127265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mAudioCommands.removeAt(k);
127365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                break;
127465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
127565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
127665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
127765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    removedCommands.clear();
127865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1279aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent    // Disable wait for status if delay is not 0.
1280aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent    // Except for create audio patch command because the returned patch handle
1281aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent    // is needed by audio policy manager
1282aa79befb301bc3451a19021b3fc9e9e6a1f231e8Eric Laurent    if (delayMs != 0 && command->mCommand != CREATE_AUDIO_PATCH) {
1283cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent        command->mWaitStatus = false;
1284cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent    }
1285cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent
128665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // insert command at the right place according to its time stamp
12871e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent    ALOGV("inserting command: %d at index %zd, num commands %zu",
12881e693b55d888b9d3e0a2ce770ae2b72b59c1a317Eric Laurent            command->mCommand, i+1, mAudioCommands.size());
128965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAudioCommands.insertAt(command, i + 1);
129065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
129165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
129265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::exit()
129365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
12943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread::exit");
129565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
129665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        AutoMutex _l(mLock);
129765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        requestExit();
129865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mWaitWorkCV.signal();
129965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
1300a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang    // Note that we can call it from the thread loop if all other references have been released
1301a754b4fa874f97a51ed2bee9257f2a870effe619Zach Jang    // but it will safely return WOULD_BLOCK in this case
130265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    requestExitAndWait();
130365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
130465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
130565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
130665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
130765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, size, "   %02d      %06d.%03d  %01u    %p\n",
130865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCommand,
130965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (int)ns2s(mTime),
131065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (int)ns2ms(mTime)%1000,
131165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mWaitStatus,
13120ede8924b98c2967be2795e8d4f9837d8d3f094cEric Laurent            mParam.get());
131365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
131465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1315fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin/******* helpers for the service_ops callbacks defined below *********/
1316fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinvoid AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
1317fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                       const char *keyValuePairs,
1318fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                       int delayMs)
1319fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
132072ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten    mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs,
1321fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                           delayMs);
1322fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1323fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1324fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::setStreamVolume(audio_stream_type_t stream,
1325fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                        float volume,
1326fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                        audio_io_handle_t output,
1327fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                        int delayMs)
1328fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1329fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten    return (int)mAudioCommandThread->volumeCommand(stream, volume,
133072ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten                                                   output, delayMs);
1331fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1332fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1333fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::startTone(audio_policy_tone_t tone,
1334fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                  audio_stream_type_t stream)
1335fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
13366e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) {
133729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("startTone: illegal tone requested (%d)", tone);
13386e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
13396e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (stream != AUDIO_STREAM_VOICE_CALL) {
134029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("startTone: illegal stream (%d) requested for tone %d", stream,
1341e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            tone);
13426e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
1343fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING,
1344fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                          AUDIO_STREAM_VOICE_CALL);
1345fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return 0;
1346fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1347fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1348fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::stopTone()
1349fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1350fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    mTonePlaybackThread->stopToneCommand();
1351fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return 0;
1352fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1353fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1354fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::setVoiceVolume(float volume, int delayMs)
1355fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1356fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
1357fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1358fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1359fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinextern "C" {
13602d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_module_handle_t aps_load_hw_module(void *service __unused,
13612d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                             const char *name);
13622d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_output(void *service __unused,
1363a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                         audio_devices_t *pDevices,
1364a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                         uint32_t *pSamplingRate,
1365a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                         audio_format_t *pFormat,
1366a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                         audio_channel_mask_t *pChannelMask,
1367a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                         uint32_t *pLatencyMs,
13682d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                         audio_output_flags_t flags);
1369fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
13702d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_output_on_module(void *service __unused,
1371a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   audio_module_handle_t module,
1372a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   audio_devices_t *pDevices,
1373a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   uint32_t *pSamplingRate,
1374a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   audio_format_t *pFormat,
1375a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   audio_channel_mask_t *pChannelMask,
1376a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   uint32_t *pLatencyMs,
1377ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald                                                   audio_output_flags_t flags,
13782d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                                   const audio_offload_info_t *offloadInfo);
13792d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_dup_output(void *service __unused,
1380fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                                 audio_io_handle_t output1,
13812d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                                 audio_io_handle_t output2);
13822d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_close_output(void *service __unused, audio_io_handle_t output);
13832d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_suspend_output(void *service __unused, audio_io_handle_t output);
13842d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_restore_output(void *service __unused, audio_io_handle_t output);
13852d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_input(void *service __unused,
1386a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                        audio_devices_t *pDevices,
1387a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                        uint32_t *pSamplingRate,
1388a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                        audio_format_t *pFormat,
1389a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                        audio_channel_mask_t *pChannelMask,
13902d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                        audio_in_acoustics_t acoustics __unused);
13912d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentaudio_io_handle_t aps_open_input_on_module(void *service __unused,
1392a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                  audio_module_handle_t module,
1393a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                  audio_devices_t *pDevices,
1394a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                  uint32_t *pSamplingRate,
1395a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                  audio_format_t *pFormat,
13962d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                                  audio_channel_mask_t *pChannelMask);
13972d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_close_input(void *service __unused, audio_io_handle_t input);
13982d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_invalidate_stream(void *service __unused, audio_stream_type_t stream);
1399d848eb48c121c119e8ba7583efc75415fe102570Glenn Kastenint aps_move_effects(void *service __unused, audio_session_t session,
1400fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                audio_io_handle_t src_output,
14012d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                audio_io_handle_t dst_output);
14022d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentchar * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle,
14032d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                     const char *keys);
14042d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentvoid aps_set_parameters(void *service, audio_io_handle_t io_handle,
14052d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                   const char *kv_pairs, int delay_ms);
14062d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_set_stream_volume(void *service, audio_stream_type_t stream,
1407fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                     float volume, audio_io_handle_t output,
14082d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                                     int delay_ms);
14092d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_start_tone(void *service, audio_policy_tone_t tone,
14102d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent                              audio_stream_type_t stream);
14112d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_stop_tone(void *service);
14122d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurentint aps_set_voice_volume(void *service, float volume, int delay_ms);
14132d388eccc9dc085337c7a03a68467cbee6b809e1Eric Laurent};
1414fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
14151b2a794a27caab3a1320d22b872b04ef73e96555Mikhail Naganov} // namespace android
1416