189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/*
289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**
389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Copyright 2008, The Android Open Source Project
489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**
589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** you may not use this file except in compliance with the License.
789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** You may obtain a copy of the License at
889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**
989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project**
1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** See the License for the specific language governing permissions and
1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** limitations under the License.
1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project*/
1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Proxy for media player implementations
1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//#define LOG_NDEBUG 0
2189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define LOG_TAG "MediaPlayerService"
2289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/Log.h>
2389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <sys/types.h>
2589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <sys/stat.h>
267cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang#include <sys/time.h>
2789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <dirent.h>
2889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <unistd.h>
2989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
3089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <string.h>
316f74b0cc490a3b8523252ded00f7ca55160effd1Mathias Agopian
3289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <cutils/atomic.h>
3314d2747c7e54037e267bcff78b29e65b2181f0faNicolas Catania#include <cutils/properties.h> // for property_get
346f74b0cc490a3b8523252ded00f7ca55160effd1Mathias Agopian
356f74b0cc490a3b8523252ded00f7ca55160effd1Mathias Agopian#include <utils/misc.h>
3689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
377562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/IPCThreadState.h>
387562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/IServiceManager.h>
397562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/MemoryHeapBase.h>
407562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/MemoryBase.h>
417dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis#include <gui/SurfaceTextureClient.h>
421d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania#include <utils/Errors.h>  // for status_t
431d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania#include <utils/String8.h>
4410dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen#include <utils/SystemClock.h>
451d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania#include <utils/Vector.h>
4689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
47e104596061b219e9bce6d4db49a9d15242f8d2e5Jeff Brown#include <media/IRemoteDisplay.h>
48e104596061b219e9bce6d4db49a9d15242f8d2e5Jeff Brown#include <media/IRemoteDisplayClient.h>
4989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/MediaPlayerInterface.h>
5089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/mediarecorder.h>
5189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/MediaMetadataRetrieverInterface.h>
52a64c8c79af1a15911c55306d83a797fa50969f77niko#include <media/Metadata.h>
5389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/AudioTrack.h>
548635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong#include <media/MemoryLeakTrackUtil.h>
559cb839a0fcc98fe4278b39afb8b6d664c04f1673Eric Laurent#include <media/stagefright/MediaErrors.h>
5689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
5764760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h>
58fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
597cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang#include <private/android_filesystem_config.h>
607cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
61559bf2836f5da25b75bfb229fec0d20d540ee426James Dong#include "ActivityManager.h"
6289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "MediaRecorderClient.h"
6389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "MediaPlayerService.h"
6489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "MetadataRetrieverClient.h"
6544a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman#include "MediaPlayerFactory.h"
6689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
6789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "MidiFile.h"
6814d2747c7e54037e267bcff78b29e65b2181f0faNicolas Catania#include "TestPlayerStub.h"
6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include "StagefrightPlayer.h"
70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "nuplayer/NuPlayerDriver.h"
7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <OMX.h>
7314d2747c7e54037e267bcff78b29e65b2181f0faNicolas Catania
74ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include "Crypto.h"
75efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber#include "HDCP.h"
76d7bee3a9d2ad76d073d91f0ee36d5ac5f9df480cAndreas Huber#include "RemoteDisplay.h"
77ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
78a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catanianamespace {
79a64c8c79af1a15911c55306d83a797fa50969f77nikousing android::media::Metadata;
80a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Cataniausing android::status_t;
81a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Cataniausing android::OK;
82a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Cataniausing android::BAD_VALUE;
83a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Cataniausing android::NOT_ENOUGH_DATA;
84a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Cataniausing android::Parcel;
85a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
86a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// Max number of entries in the filter.
87a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Cataniaconst int kMaxFilterSize = 64;  // I pulled that out of thin air.
88a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
89a64c8c79af1a15911c55306d83a797fa50969f77niko// FIXME: Move all the metadata related function in the Metadata.cpp
90d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cniko
91a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
92a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// Unmarshall a filter from a Parcel.
93a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// Filter format in a parcel:
94a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania//
95a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
96a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
97a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// |                       number of entries (n)                   |
98a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
99a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// |                       metadata type 1                         |
100a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
101a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// |                       metadata type 2                         |
102a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
103a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania//  ....
104a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
105a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// |                       metadata type n                         |
106a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
107a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania//
108a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// @param p Parcel that should start with a filter.
109a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// @param[out] filter On exit contains the list of metadata type to be
110a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania//                    filtered.
111a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// @param[out] status On exit contains the status code to be returned.
112a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// @return true if the parcel starts with a valid filter.
113a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Cataniabool unmarshallFilter(const Parcel& p,
114a64c8c79af1a15911c55306d83a797fa50969f77niko                      Metadata::Filter *filter,
115a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania                      status_t *status)
116a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania{
1174829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    int32_t val;
1184829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    if (p.readInt32(&val) != OK)
119a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    {
12029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to read filter's length");
121a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        *status = NOT_ENOUGH_DATA;
122a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        return false;
123a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    }
124a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
1254829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    if( val > kMaxFilterSize || val < 0)
126a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    {
12729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid filter len %d", val);
128a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        *status = BAD_VALUE;
129a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        return false;
130a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    }
131a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
1324829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    const size_t num = val;
133a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
134a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    filter->clear();
1354829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    filter->setCapacity(num);
136a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
137a64c8c79af1a15911c55306d83a797fa50969f77niko    size_t size = num * sizeof(Metadata::Type);
138a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
1394829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania
1404829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    if (p.dataAvail() < size)
141a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    {
14229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Filter too short expected %d but got %d", size, p.dataAvail());
143a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        *status = NOT_ENOUGH_DATA;
144a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        return false;
145a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    }
146a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
147a64c8c79af1a15911c55306d83a797fa50969f77niko    const Metadata::Type *data =
148a64c8c79af1a15911c55306d83a797fa50969f77niko            static_cast<const Metadata::Type*>(p.readInplace(size));
149a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
1504829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    if (NULL == data)
151a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    {
15229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Filter had no data");
153a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        *status = BAD_VALUE;
154a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        return false;
155a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    }
156a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
157a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    // TODO: The stl impl of vector would be more efficient here
158a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    // because it degenerates into a memcpy on pod types. Try to
159a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    // replace later or use stl::set.
1604829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    for (size_t i = 0; i < num; ++i)
161a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    {
1624829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania        filter->add(*data);
163a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        ++data;
164a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    }
165a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    *status = OK;
166a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    return true;
167a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania}
168a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
1694829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania// @param filter Of metadata type.
170a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// @param val To be searched.
171a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// @return true if a match was found.
172a64c8c79af1a15911c55306d83a797fa50969f77nikobool findMetadata(const Metadata::Filter& filter, const int32_t val)
173a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania{
174a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    // Deal with empty and ANY right away
175a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    if (filter.isEmpty()) return false;
176a64c8c79af1a15911c55306d83a797fa50969f77niko    if (filter[0] == Metadata::kAny) return true;
177a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
1784829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    return filter.indexOf(val) >= 0;
179a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania}
180a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
181a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania}  // anonymous namespace
182a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
183a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
18489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android {
18589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
186d681bbb1767bed09415e050ba78975df214bcd68Dave Burkestatic bool checkPermission(const char* permissionString) {
187d681bbb1767bed09415e050ba78975df214bcd68Dave Burke#ifndef HAVE_ANDROID_OS
188d681bbb1767bed09415e050ba78975df214bcd68Dave Burke    return true;
189d681bbb1767bed09415e050ba78975df214bcd68Dave Burke#endif
190d681bbb1767bed09415e050ba78975df214bcd68Dave Burke    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
191d681bbb1767bed09415e050ba78975df214bcd68Dave Burke    bool ok = checkCallingPermission(String16(permissionString));
19229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    if (!ok) ALOGE("Request requires %s", permissionString);
193d681bbb1767bed09415e050ba78975df214bcd68Dave Burke    return ok;
194d681bbb1767bed09415e050ba78975df214bcd68Dave Burke}
195d681bbb1767bed09415e050ba78975df214bcd68Dave Burke
19689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// TODO: Find real cause of Audio/Video delay in PV framework and remove this workaround
19789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/* static */ int MediaPlayerService::AudioOutput::mMinBufferCount = 4;
19889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/* static */ bool MediaPlayerService::AudioOutput::mIsOnEmulator = false;
19989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
20089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid MediaPlayerService::instantiate() {
20189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    defaultServiceManager()->addService(
20289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            String16("media.player"), new MediaPlayerService());
20389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
20489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
20589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMediaPlayerService::MediaPlayerService()
20689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
2073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("MediaPlayerService created");
20889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mNextConnId = 1;
2099ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
2109ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    mBatteryAudio.refCount = 0;
2119ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
2129ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        mBatteryAudio.deviceOn[i] = 0;
2139ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        mBatteryAudio.lastTime[i] = 0;
2149ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        mBatteryAudio.totalTime[i] = 0;
2159ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    }
2169ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    // speaker is on by default
2179ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    mBatteryAudio.deviceOn[SPEAKER] = 1;
21844a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman
21944a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman    MediaPlayerFactory::registerBuiltinFactories();
22089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
22189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
22289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMediaPlayerService::~MediaPlayerService()
22389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
2243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("MediaPlayerService destroyed");
22589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
22689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
22789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectsp<IMediaRecorder> MediaPlayerService::createMediaRecorder(pid_t pid)
22889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
229dac6a31a33ba53fb93850670cdddd1e6515dadceGloria Wang    sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid);
230dac6a31a33ba53fb93850670cdddd1e6515dadceGloria Wang    wp<MediaRecorderClient> w = recorder;
231dac6a31a33ba53fb93850670cdddd1e6515dadceGloria Wang    Mutex::Autolock lock(mLock);
232dac6a31a33ba53fb93850670cdddd1e6515dadceGloria Wang    mMediaRecorderClients.add(w);
2333856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Create new media recorder client from pid %d", pid);
23489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return recorder;
23589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
23689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
237dac6a31a33ba53fb93850670cdddd1e6515dadceGloria Wangvoid MediaPlayerService::removeMediaRecorderClient(wp<MediaRecorderClient> client)
238dac6a31a33ba53fb93850670cdddd1e6515dadceGloria Wang{
239dac6a31a33ba53fb93850670cdddd1e6515dadceGloria Wang    Mutex::Autolock lock(mLock);
240dac6a31a33ba53fb93850670cdddd1e6515dadceGloria Wang    mMediaRecorderClients.remove(client);
2413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Delete media recorder client");
242dac6a31a33ba53fb93850670cdddd1e6515dadceGloria Wang}
243dac6a31a33ba53fb93850670cdddd1e6515dadceGloria Wang
24489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectsp<IMediaMetadataRetriever> MediaPlayerService::createMetadataRetriever(pid_t pid)
24589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
24689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MetadataRetrieverClient> retriever = new MetadataRetrieverClient(pid);
2473856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Create new media retriever from pid %d", pid);
24889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return retriever;
24989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
25089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
25189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectsp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client,
252d681bbb1767bed09415e050ba78975df214bcd68Dave Burke        int audioSessionId)
25389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
25489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int32_t connId = android_atomic_inc(&mNextConnId);
2559b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
2569b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    sp<Client> c = new Client(
2579b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber            this, pid, connId, client, audioSessionId,
2589b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber            IPCThreadState::self()->getCallingUid());
2599b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
2603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Create new client(%d) from pid %d, uid %d, ", connId, pid,
261d681bbb1767bed09415e050ba78975df214bcd68Dave Burke         IPCThreadState::self()->getCallingUid());
262e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
263d681bbb1767bed09415e050ba78975df214bcd68Dave Burke    wp<Client> w = c;
264d681bbb1767bed09415e050ba78975df214bcd68Dave Burke    {
265e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        Mutex::Autolock lock(mLock);
266e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        mClients.add(w);
267e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
268e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    return c;
269e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
270e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
271318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Hubersp<IOMX> MediaPlayerService::getOMX() {
272318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    Mutex::Autolock autoLock(mLock);
273318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
274318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    if (mOMX.get() == NULL) {
275318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber        mOMX = new OMX;
276318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    }
277318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber
278318ad9c1d9d6515026dfc2c021359d27decaa7a1Andreas Huber    return mOMX;
27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
281ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Hubersp<ICrypto> MediaPlayerService::makeCrypto() {
2821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    return new Crypto;
283ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}
284ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
285efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Hubersp<IHDCP> MediaPlayerService::makeHDCP() {
286efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber    return new HDCP;
287efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber}
288efbb781c15abf8e085f5ab8d39710bd58ea0b6e4Andreas Huber
289e104596061b219e9bce6d4db49a9d15242f8d2e5Jeff Brownsp<IRemoteDisplay> MediaPlayerService::listenForRemoteDisplay(
290e104596061b219e9bce6d4db49a9d15242f8d2e5Jeff Brown        const sp<IRemoteDisplayClient>& client, const String8& iface) {
291b019250df516e094b0cb648851f9a132b045378aJeff Brown    if (!checkPermission("android.permission.CONTROL_WIFI_DISPLAY")) {
292b019250df516e094b0cb648851f9a132b045378aJeff Brown        return NULL;
293b019250df516e094b0cb648851f9a132b045378aJeff Brown    }
294b019250df516e094b0cb648851f9a132b045378aJeff Brown
295455d02eca342d8159637af317a5d83219d267812Jeff Brown    return new RemoteDisplay(client, iface.string());
296e104596061b219e9bce6d4db49a9d15242f8d2e5Jeff Brown}
297e104596061b219e9bce6d4db49a9d15242f8d2e5Jeff Brown
29889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayerService::AudioCache::dump(int fd, const Vector<String16>& args) const
29989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
30089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const size_t SIZE = 256;
30189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    char buffer[SIZE];
30289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    String8 result;
30389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
30489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result.append(" AudioCache\n");
30589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mHeap != 0) {
30689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        snprintf(buffer, 255, "  heap base(%p), size(%d), flags(%d), device(%s)\n",
30789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                mHeap->getBase(), mHeap->getSize(), mHeap->getFlags(), mHeap->getDevice());
30889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        result.append(buffer);
30989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
31089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    snprintf(buffer, 255, "  msec per frame(%f), channel count(%d), format(%d), frame count(%ld)\n",
31189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mMsecsPerFrame, mChannelCount, mFormat, mFrameCount);
31289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result.append(buffer);
31389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    snprintf(buffer, 255, "  sample rate(%d), size(%d), error(%d), command complete(%s)\n",
31489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mSampleRate, mSize, mError, mCommandComplete?"true":"false");
31589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result.append(buffer);
31689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    ::write(fd, result.string(), result.size());
31789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
31889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
31989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
32089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayerService::AudioOutput::dump(int fd, const Vector<String16>& args) const
32189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
32289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const size_t SIZE = 256;
32389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    char buffer[SIZE];
32489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    String8 result;
32589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
32689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result.append(" AudioOutput\n");
32789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    snprintf(buffer, 255, "  stream type(%d), left - right volume(%f, %f)\n",
32889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mStreamType, mLeftVolume, mRightVolume);
32989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result.append(buffer);
33089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    snprintf(buffer, 255, "  msec per frame(%f), latency (%d)\n",
331db354e58e65592777aa17caa47933e14838b8b35Eric Laurent            mMsecsPerFrame, (mTrack != 0) ? mTrack->latency() : -1);
33289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result.append(buffer);
3332beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    snprintf(buffer, 255, "  aux effect id(%d), send level (%f)\n",
3342beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent            mAuxEffectId, mSendLevel);
3352beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    result.append(buffer);
3362beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent
33789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    ::write(fd, result.string(), result.size());
33889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mTrack != 0) {
33989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mTrack->dump(fd, args);
34089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
34189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
34289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
34389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
34489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayerService::Client::dump(int fd, const Vector<String16>& args) const
34589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
34689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const size_t SIZE = 256;
34789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    char buffer[SIZE];
34889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    String8 result;
34989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result.append(" Client\n");
35089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    snprintf(buffer, 255, "  pid(%d), connId(%d), status(%d), looping(%s)\n",
35189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            mPid, mConnId, mStatus, mLoop?"true": "false");
35289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result.append(buffer);
35389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    write(fd, result.string(), result.size());
354a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    if (mPlayer != NULL) {
355a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber        mPlayer->dump(fd, args);
356a0b1d4b161599c2bb2a47119e50c51e75bbe980eAndreas Huber    }
35789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mAudioOutput != 0) {
35889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mAudioOutput->dump(fd, args);
35989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
36089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    write(fd, "\n", 1);
36189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
36289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
36389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
36489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayerService::dump(int fd, const Vector<String16>& args)
36589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
36689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const size_t SIZE = 256;
36789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    char buffer[SIZE];
36889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    String8 result;
36989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
37089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        snprintf(buffer, SIZE, "Permission Denial: "
37189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                "can't dump MediaPlayerService from pid=%d, uid=%d\n",
37289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                IPCThreadState::self()->getCallingPid(),
37389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                IPCThreadState::self()->getCallingUid());
37489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        result.append(buffer);
37589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else {
37689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Mutex::Autolock lock(mLock);
37789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        for (int i = 0, n = mClients.size(); i < n; ++i) {
37889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            sp<Client> c = mClients[i].promote();
37989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (c != 0) c->dump(fd, args);
38089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
381b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong        if (mMediaRecorderClients.size() == 0) {
382b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong                result.append(" No media recorder client\n\n");
383b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong        } else {
384b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong            for (int i = 0, n = mMediaRecorderClients.size(); i < n; ++i) {
385b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong                sp<MediaRecorderClient> c = mMediaRecorderClients[i].promote();
386e579e28089c6b86f56d257030b778c5e22b1a5a5James Dong                if (c != 0) {
387e579e28089c6b86f56d257030b778c5e22b1a5a5James Dong                    snprintf(buffer, 255, " MediaRecorderClient pid(%d)\n", c->mPid);
388e579e28089c6b86f56d257030b778c5e22b1a5a5James Dong                    result.append(buffer);
389e579e28089c6b86f56d257030b778c5e22b1a5a5James Dong                    write(fd, result.string(), result.size());
390e579e28089c6b86f56d257030b778c5e22b1a5a5James Dong                    result = "\n";
391e579e28089c6b86f56d257030b778c5e22b1a5a5James Dong                    c->dump(fd, args);
392e579e28089c6b86f56d257030b778c5e22b1a5a5James Dong                }
393b914122eb9cb54bbeae4ec03bfebb194aecdccbdJames Dong            }
394dac6a31a33ba53fb93850670cdddd1e6515dadceGloria Wang        }
395dac6a31a33ba53fb93850670cdddd1e6515dadceGloria Wang
39689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        result.append(" Files opened and/or mapped:\n");
3970512ab559d4670c2204078470d7ef5d376811c57Glenn Kasten        snprintf(buffer, SIZE, "/proc/%d/maps", gettid());
39889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        FILE *f = fopen(buffer, "r");
39989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (f) {
40089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            while (!feof(f)) {
40189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                fgets(buffer, SIZE, f);
40273ac1eebff620714c6977f7342ff8dcc4858b3cfMarco Nelissen                if (strstr(buffer, " /storage/") ||
40389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    strstr(buffer, " /system/sounds/") ||
40402fa834249a01144d6f23137951538600aa5d611Dave Sparks                    strstr(buffer, " /data/") ||
40589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    strstr(buffer, " /system/media/")) {
40689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    result.append("  ");
40789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    result.append(buffer);
40889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                }
40989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            }
41089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            fclose(f);
41189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
41289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            result.append("couldn't open ");
41389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            result.append(buffer);
41489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            result.append("\n");
41589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
41689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4170512ab559d4670c2204078470d7ef5d376811c57Glenn Kasten        snprintf(buffer, SIZE, "/proc/%d/fd", gettid());
41889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DIR *d = opendir(buffer);
41989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (d) {
42089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            struct dirent *ent;
42189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            while((ent = readdir(d)) != NULL) {
42289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) {
4230512ab559d4670c2204078470d7ef5d376811c57Glenn Kasten                    snprintf(buffer, SIZE, "/proc/%d/fd/%s", gettid(), ent->d_name);
42489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    struct stat s;
42589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    if (lstat(buffer, &s) == 0) {
42689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                        if ((s.st_mode & S_IFMT) == S_IFLNK) {
42789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                            char linkto[256];
42889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                            int len = readlink(buffer, linkto, sizeof(linkto));
42989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                            if(len > 0) {
43089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                if(len > 255) {
43189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                    linkto[252] = '.';
43289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                    linkto[253] = '.';
43389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                    linkto[254] = '.';
43489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                    linkto[255] = 0;
43589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                } else {
43689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                    linkto[len] = 0;
43789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                }
43873ac1eebff620714c6977f7342ff8dcc4858b3cfMarco Nelissen                                if (strstr(linkto, "/storage/") == linkto ||
43989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                    strstr(linkto, "/system/sounds/") == linkto ||
44002fa834249a01144d6f23137951538600aa5d611Dave Sparks                                    strstr(linkto, "/data/") == linkto ||
44189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                    strstr(linkto, "/system/media/") == linkto) {
44289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                    result.append("  ");
44389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                    result.append(buffer);
44489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                    result.append(" -> ");
44589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                    result.append(linkto);
44689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                    result.append("\n");
44789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                }
44889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                            }
44989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                        } else {
45089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                            result.append("  unexpected type for ");
45189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                            result.append(buffer);
45289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                            result.append("\n");
45389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                        }
45489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                    }
45589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                }
45689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            }
45789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            closedir(d);
45889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
45989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            result.append("couldn't open ");
46089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            result.append(buffer);
46189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            result.append("\n");
46289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
46389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
46489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        bool dumpMem = false;
46589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        for (size_t i = 0; i < args.size(); i++) {
46689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            if (args[i] == String16("-m")) {
46789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                dumpMem = true;
46889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            }
46989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
47089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (dumpMem) {
4718635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong            dumpMemoryAddresses(fd);
47289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
47389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
47489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    write(fd, result.string(), result.size());
47589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
47689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
47789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
47889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid MediaPlayerService::removeClient(wp<Client> client)
47989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
48089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock lock(mLock);
48189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mClients.remove(client);
48289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
48389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4849b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas HuberMediaPlayerService::Client::Client(
4859b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber        const sp<MediaPlayerService>& service, pid_t pid,
4869b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber        int32_t connId, const sp<IMediaPlayerClient>& client,
4879b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber        int audioSessionId, uid_t uid)
48889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
4893856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Client(%d) constructor", connId);
49089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mPid = pid;
49189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mConnId = connId;
49289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mService = service;
49389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mClient = client;
49489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mLoop = false;
49589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mStatus = NO_INIT;
496a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent    mAudioSessionId = audioSessionId;
4979b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber    mUID = uid;
498c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    mRetransmitEndpointValid = false;
499a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent
50089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#if CALLBACK_ANTAGONIZER
501b8a805261bf0282e992d3608035e47d05a898710Steve Block    ALOGD("create Antagonizer");
50289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mAntagonizer = new Antagonizer(notify, this);
50389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#endif
50489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
50589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
50689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMediaPlayerService::Client::~Client()
50789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
5083856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Client(%d) destructor pid = %d", mConnId, mPid);
50989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mAudioOutput.clear();
51089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    wp<Client> client(this);
51189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    disconnect();
51289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mService->removeClient(client);
51389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
51489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
51589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid MediaPlayerService::Client::disconnect()
51689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
5173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("disconnect(%d) from pid %d", mConnId, mPid);
51889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // grab local reference and clear main reference to prevent future
51989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // access to object
52089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MediaPlayerBase> p;
52189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    {
52289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Mutex::Autolock l(mLock);
52389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        p = mPlayer;
52489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
525795fa5848276bab87445fa64fd0941c13ef62398Dave Sparks    mClient.clear();
52620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
52789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mPlayer.clear();
52889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
52989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // clear the notification to prevent callbacks to dead client
53089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // and reset the player. We assume the player will serialize
53189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // access to itself if necessary.
53289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (p != 0) {
53389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        p->setNotifyCallback(0, 0);
53489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#if CALLBACK_ANTAGONIZER
535b8a805261bf0282e992d3608035e47d05a898710Steve Block        ALOGD("kill Antagonizer");
53689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mAntagonizer->kill();
53789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#endif
53889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        p->reset();
53989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
54089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
5417dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    disconnectNativeWindow();
5427dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis
54389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    IPCThreadState::self()->flushCommands();
54489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
54589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
54689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectsp<MediaPlayerBase> MediaPlayerService::Client::createPlayer(player_type playerType)
54789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
54889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // determine if we have the right player type
54989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MediaPlayerBase> p = mPlayer;
55089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if ((p != NULL) && (p->playerType() != playerType)) {
5513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("delete player");
55289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        p.clear();
55389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
55489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (p == NULL) {
55544a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman        p = MediaPlayerFactory::createPlayer(playerType, this, notify);
55689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
5579b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
558db29e5238e28d59978755a2ff2e7e0f05393abdfJason Simmons    if (p != NULL) {
559db29e5238e28d59978755a2ff2e7e0f05393abdfJason Simmons        p->setUID(mUID);
560db29e5238e28d59978755a2ff2e7e0f05393abdfJason Simmons    }
5619b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber
56289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return p;
56389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
56489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
565c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossmansp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(
566c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        player_type playerType)
567c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman{
568c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    ALOGV("player type = %d", playerType);
569c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
570c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    // create the right type of player
571c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    sp<MediaPlayerBase> p = createPlayer(playerType);
572c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    if (p == NULL) {
573c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        return p;
574c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    }
575c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
576c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    if (!p->hardwareOutput()) {
577c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        mAudioOutput = new AudioOutput(mAudioSessionId);
578c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
579c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    }
580c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
581c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    return p;
582c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman}
583c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
584c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossmanvoid MediaPlayerService::Client::setDataSource_post(
585c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        const sp<MediaPlayerBase>& p,
586c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        status_t status)
587c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman{
588c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    ALOGV(" setDataSource");
589c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    mStatus = status;
590c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    if (mStatus != OK) {
591c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        ALOGE("  error: %d", mStatus);
592c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        return;
593c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    }
594c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
595c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    // Set the re-transmission endpoint if one was chosen.
596c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    if (mRetransmitEndpointValid) {
597c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        mStatus = p->setRetransmitEndpoint(&mRetransmitEndpoint);
598c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        if (mStatus != NO_ERROR) {
599c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman            ALOGE("setRetransmitEndpoint error: %d", mStatus);
600c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        }
601c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    }
602c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
603c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    if (mStatus == OK) {
604c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        mPlayer = p;
605c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    }
606c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman}
607c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
6082db8455d8f4468a637109d31f319ce02d9d743ecAndreas Huberstatus_t MediaPlayerService::Client::setDataSource(
6092db8455d8f4468a637109d31f319ce02d9d743ecAndreas Huber        const char *url, const KeyedVector<String8, String8> *headers)
61089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
6113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setDataSource(%s)", url);
61289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (url == NULL)
61389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return UNKNOWN_ERROR;
61489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
615d681bbb1767bed09415e050ba78975df214bcd68Dave Burke    if ((strncmp(url, "http://", 7) == 0) ||
616d681bbb1767bed09415e050ba78975df214bcd68Dave Burke        (strncmp(url, "https://", 8) == 0) ||
617d681bbb1767bed09415e050ba78975df214bcd68Dave Burke        (strncmp(url, "rtsp://", 7) == 0)) {
618d681bbb1767bed09415e050ba78975df214bcd68Dave Burke        if (!checkPermission("android.permission.INTERNET")) {
619d681bbb1767bed09415e050ba78975df214bcd68Dave Burke            return PERMISSION_DENIED;
620d681bbb1767bed09415e050ba78975df214bcd68Dave Burke        }
621d681bbb1767bed09415e050ba78975df214bcd68Dave Burke    }
622d681bbb1767bed09415e050ba78975df214bcd68Dave Burke
62389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (strncmp(url, "content://", 10) == 0) {
62489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // get a filedescriptor for the content Uri and
62589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        // pass it to the setDataSource(fd) method
62689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
62789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        String16 url16(url);
62889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int fd = android::openContentProviderFile(url16);
62989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (fd < 0)
63089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        {
63129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Couldn't open fd for %s", url);
63289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            return UNKNOWN_ERROR;
63389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
63489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        setDataSource(fd, 0, 0x7fffffffffLL); // this sets mStatus
63589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        close(fd);
63689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return mStatus;
63789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else {
63844a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman        player_type playerType = MediaPlayerFactory::getPlayerType(this, url);
639c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        sp<MediaPlayerBase> p = setDataSource_pre(playerType);
640c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        if (p == NULL) {
641c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman            return NO_INIT;
64289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
64389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
644c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        setDataSource_post(p, p->setDataSource(url, headers));
64589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return mStatus;
64689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
64789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
64889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
64989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)
65089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
6513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length);
65289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    struct stat sb;
65389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int ret = fstat(fd, &sb);
65489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (ret != 0) {
65529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno));
65689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return UNKNOWN_ERROR;
65789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
65889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
6593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("st_dev  = %llu", sb.st_dev);
6603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("st_mode = %u", sb.st_mode);
6613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("st_uid  = %lu", sb.st_uid);
6623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("st_gid  = %lu", sb.st_gid);
6633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("st_size = %llu", sb.st_size);
66489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
66589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (offset >= sb.st_size) {
66629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("offset error");
66789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        ::close(fd);
66889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return UNKNOWN_ERROR;
66989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
67089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (offset + length > sb.st_size) {
67189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        length = sb.st_size - offset;
6723856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("calculated length = %lld", length);
67389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
67489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
67544a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman    player_type playerType = MediaPlayerFactory::getPlayerType(this,
67644a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman                                                               fd,
67744a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman                                                               offset,
67844a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman                                                               length);
679c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    sp<MediaPlayerBase> p = setDataSource_pre(playerType);
680c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    if (p == NULL) {
681c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        return NO_INIT;
68289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
68389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
68489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // now set data source
685c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    setDataSource_post(p, p->setDataSource(fd, offset, length));
68689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mStatus;
68789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
68889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
689e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huberstatus_t MediaPlayerService::Client::setDataSource(
690e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        const sp<IStreamSource> &source) {
691e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    // create the right type of player
69244a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman    player_type playerType = MediaPlayerFactory::getPlayerType(this, source);
693c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    sp<MediaPlayerBase> p = setDataSource_pre(playerType);
694e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    if (p == NULL) {
695e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber        return NO_INIT;
696e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    }
697e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
698e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    // now set data source
699c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    setDataSource_post(p, p->setDataSource(source));
700e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber    return mStatus;
701e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber}
702e2b1028852120bcfded33b8f06f66b780437fe92Andreas Huber
7037dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennisvoid MediaPlayerService::Client::disconnectNativeWindow() {
7047dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    if (mConnectedWindow != NULL) {
7057dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis        status_t err = native_window_api_disconnect(mConnectedWindow.get(),
7067dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis                NATIVE_WINDOW_API_MEDIA);
7077dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis
7087dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis        if (err != OK) {
7095ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("native_window_api_disconnect returned an error: %s (%d)",
7107dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis                    strerror(-err), err);
7117dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis        }
7127dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    }
7137dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    mConnectedWindow.clear();
7147dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis}
7157dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis
7161173118eace0e9e347cb007f0da817cee87579edGlenn Kastenstatus_t MediaPlayerService::Client::setVideoSurfaceTexture(
7171173118eace0e9e347cb007f0da817cee87579edGlenn Kasten        const sp<ISurfaceTexture>& surfaceTexture)
7181173118eace0e9e347cb007f0da817cee87579edGlenn Kasten{
7193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%d] setVideoSurfaceTexture(%p)", mConnId, surfaceTexture.get());
7201173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    sp<MediaPlayerBase> p = getPlayer();
7211173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    if (p == 0) return UNKNOWN_ERROR;
7227dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis
7237dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    sp<IBinder> binder(surfaceTexture == NULL ? NULL :
7247dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis            surfaceTexture->asBinder());
7257dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    if (mConnectedWindowBinder == binder) {
7267dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis        return OK;
7277dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    }
7287dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis
7297dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    sp<ANativeWindow> anw;
7307dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    if (surfaceTexture != NULL) {
7317dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis        anw = new SurfaceTextureClient(surfaceTexture);
7327dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis        status_t err = native_window_api_connect(anw.get(),
7337dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis                NATIVE_WINDOW_API_MEDIA);
7347dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis
7357dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis        if (err != OK) {
73629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("setVideoSurfaceTexture failed: %d", err);
7377dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis            // Note that we must do the reset before disconnecting from the ANW.
7387dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis            // Otherwise queue/dequeue calls could be made on the disconnected
7397dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis            // ANW, which may result in errors.
7407dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis            reset();
7417dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis
7427dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis            disconnectNativeWindow();
7437dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis
7447dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis            return err;
7457dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis        }
7467dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    }
7477dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis
7487dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    // Note that we must set the player's new SurfaceTexture before
7497dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    // disconnecting the old one.  Otherwise queue/dequeue calls could be made
7507dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    // on the disconnected ANW, which may result in errors.
7517dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    status_t err = p->setVideoSurfaceTexture(surfaceTexture);
7527dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis
7537dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    disconnectNativeWindow();
7547dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis
7557dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    mConnectedWindow = anw;
7567dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis
7577dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    if (err == OK) {
7587dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis        mConnectedWindowBinder = binder;
7597dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    } else {
7607dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis        disconnectNativeWindow();
7617dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    }
7627dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis
7637dae00baa6e8957be15523c46bb948bd1dde64c3Jamie Gennis    return err;
7641173118eace0e9e347cb007f0da817cee87579edGlenn Kasten}
7651173118eace0e9e347cb007f0da817cee87579edGlenn Kasten
7661d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Cataniastatus_t MediaPlayerService::Client::invoke(const Parcel& request,
7671d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania                                            Parcel *reply)
7681d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania{
7691d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania    sp<MediaPlayerBase> p = getPlayer();
7701d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania    if (p == NULL) return UNKNOWN_ERROR;
7711d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania    return p->invoke(request, reply);
7721d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania}
7731d187f1a86855f5f0694d7ec30efc9833bf7c589Nicolas Catania
774a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania// This call doesn't need to access the native player.
775a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Cataniastatus_t MediaPlayerService::Client::setMetadataFilter(const Parcel& filter)
776a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania{
777a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    status_t status;
778a64c8c79af1a15911c55306d83a797fa50969f77niko    media::Metadata::Filter allow, drop;
779a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
7804829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    if (unmarshallFilter(filter, &allow, &status) &&
7814829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania        unmarshallFilter(filter, &drop, &status)) {
7824829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania        Mutex::Autolock lock(mLock);
783a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
784a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        mMetadataAllow = allow;
785a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        mMetadataDrop = drop;
786a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    }
787a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    return status;
788a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania}
789a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
7904829038419910aa6e75ce8992d45a223452d5c67Nicolas Cataniastatus_t MediaPlayerService::Client::getMetadata(
7914829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania        bool update_only, bool apply_filter, Parcel *reply)
7928e1b6cce24574b9ecd5b0300155776bd0b4ef756Nicolas Catania{
793a64c8c79af1a15911c55306d83a797fa50969f77niko    sp<MediaPlayerBase> player = getPlayer();
794a64c8c79af1a15911c55306d83a797fa50969f77niko    if (player == 0) return UNKNOWN_ERROR;
795d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cniko
7968e1b6cce24574b9ecd5b0300155776bd0b4ef756Nicolas Catania    status_t status;
797d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cniko    // Placeholder for the return code, updated by the caller.
798d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cniko    reply->writeInt32(-1);
7994829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania
800a64c8c79af1a15911c55306d83a797fa50969f77niko    media::Metadata::Filter ids;
8014829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania
8024829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    // We don't block notifications while we fetch the data. We clear
8034829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    // mMetadataUpdated first so we don't lose notifications happening
8044829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    // during the rest of this call.
8054829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    {
8064829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania        Mutex::Autolock lock(mLock);
8074829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania        if (update_only) {
808d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cniko            ids = mMetadataUpdated;
8094829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania        }
8104829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania        mMetadataUpdated.clear();
8114829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    }
8128e1b6cce24574b9ecd5b0300155776bd0b4ef756Nicolas Catania
813a64c8c79af1a15911c55306d83a797fa50969f77niko    media::Metadata metadata(reply);
8144829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania
815a64c8c79af1a15911c55306d83a797fa50969f77niko    metadata.appendHeader();
816a64c8c79af1a15911c55306d83a797fa50969f77niko    status = player->getMetadata(ids, reply);
817d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cniko
818d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cniko    if (status != OK) {
819a64c8c79af1a15911c55306d83a797fa50969f77niko        metadata.resetParcel();
82029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("getMetadata failed %d", status);
821d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cniko        return status;
822d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cniko    }
823d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cniko
824d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cniko    // FIXME: Implement filtering on the result. Not critical since
825d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cniko    // filtering takes place on the update notifications already. This
826d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cniko    // would be when all the metadata are fetch and a filter is set.
827d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cniko
828d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cniko    // Everything is fine, update the metadata length.
829a64c8c79af1a15911c55306d83a797fa50969f77niko    metadata.updateLength();
830d608a813a9d2cbc6e2a5ea81d78d4a9044090c4cniko    return OK;
8318e1b6cce24574b9ecd5b0300155776bd0b4ef756Nicolas Catania}
8328e1b6cce24574b9ecd5b0300155776bd0b4ef756Nicolas Catania
83389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayerService::Client::prepareAsync()
83489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
8353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%d] prepareAsync", mConnId);
83689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MediaPlayerBase> p = getPlayer();
83789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (p == 0) return UNKNOWN_ERROR;
83889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t ret = p->prepareAsync();
83989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#if CALLBACK_ANTAGONIZER
840b8a805261bf0282e992d3608035e47d05a898710Steve Block    ALOGD("start Antagonizer");
84189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (ret == NO_ERROR) mAntagonizer->start();
84289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#endif
84389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return ret;
84489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
84589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
84689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayerService::Client::start()
84789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
8483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%d] start", mConnId);
84989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MediaPlayerBase> p = getPlayer();
85089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (p == 0) return UNKNOWN_ERROR;
85189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    p->setLooping(mLoop);
85289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return p->start();
85389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
85489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
85589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayerService::Client::stop()
85689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
8573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%d] stop", mConnId);
85889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MediaPlayerBase> p = getPlayer();
85989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (p == 0) return UNKNOWN_ERROR;
86089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return p->stop();
86189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
86289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
86389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayerService::Client::pause()
86489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
8653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%d] pause", mConnId);
86689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MediaPlayerBase> p = getPlayer();
86789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (p == 0) return UNKNOWN_ERROR;
86889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return p->pause();
86989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
87089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
87189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayerService::Client::isPlaying(bool* state)
87289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
87389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *state = false;
87489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MediaPlayerBase> p = getPlayer();
87589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (p == 0) return UNKNOWN_ERROR;
87689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *state = p->isPlaying();
8773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%d] isPlaying: %d", mConnId, *state);
87889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
87989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
88089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
88189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayerService::Client::getCurrentPosition(int *msec)
88289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
8833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("getCurrentPosition");
88489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MediaPlayerBase> p = getPlayer();
88589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (p == 0) return UNKNOWN_ERROR;
88689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t ret = p->getCurrentPosition(msec);
88789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (ret == NO_ERROR) {
8883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%d] getCurrentPosition = %d", mConnId, *msec);
88989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else {
89029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("getCurrentPosition returned %d", ret);
89189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
89289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return ret;
89389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
89489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
89589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayerService::Client::getDuration(int *msec)
89689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
8973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("getDuration");
89889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MediaPlayerBase> p = getPlayer();
89989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (p == 0) return UNKNOWN_ERROR;
90089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    status_t ret = p->getDuration(msec);
90189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (ret == NO_ERROR) {
9023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("[%d] getDuration = %d", mConnId, *msec);
90389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else {
90429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("getDuration returned %d", ret);
90589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
90689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return ret;
90789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
90889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
9096b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissenstatus_t MediaPlayerService::Client::setNextPlayer(const sp<IMediaPlayer>& player) {
9106b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    ALOGV("setNextPlayer");
9116b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    Mutex::Autolock l(mLock);
9126b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    sp<Client> c = static_cast<Client*>(player.get());
9136b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    mNextClient = c;
9142e5f22e85d177b34e790f832789d03aee438a7dbJohn Grossman
9152e5f22e85d177b34e790f832789d03aee438a7dbJohn Grossman    if (c != NULL) {
9162e5f22e85d177b34e790f832789d03aee438a7dbJohn Grossman        if (mAudioOutput != NULL) {
9172e5f22e85d177b34e790f832789d03aee438a7dbJohn Grossman            mAudioOutput->setNextOutput(c->mAudioOutput);
9182e5f22e85d177b34e790f832789d03aee438a7dbJohn Grossman        } else if ((mPlayer != NULL) && !mPlayer->hardwareOutput()) {
9192e5f22e85d177b34e790f832789d03aee438a7dbJohn Grossman            ALOGE("no current audio output");
9202e5f22e85d177b34e790f832789d03aee438a7dbJohn Grossman        }
9212e5f22e85d177b34e790f832789d03aee438a7dbJohn Grossman
9222e5f22e85d177b34e790f832789d03aee438a7dbJohn Grossman        if ((mPlayer != NULL) && (mNextClient->getPlayer() != NULL)) {
9232e5f22e85d177b34e790f832789d03aee438a7dbJohn Grossman            mPlayer->setNextPlayer(mNextClient->getPlayer());
9242e5f22e85d177b34e790f832789d03aee438a7dbJohn Grossman        }
9256b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    }
9262e5f22e85d177b34e790f832789d03aee438a7dbJohn Grossman
9276b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    return OK;
9286b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen}
9296b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen
93089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayerService::Client::seekTo(int msec)
93189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
9323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%d] seekTo(%d)", mConnId, msec);
93389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MediaPlayerBase> p = getPlayer();
93489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (p == 0) return UNKNOWN_ERROR;
93589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return p->seekTo(msec);
93689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
93789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
93889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayerService::Client::reset()
93989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
9403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%d] reset", mConnId);
941c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    mRetransmitEndpointValid = false;
94289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MediaPlayerBase> p = getPlayer();
94389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (p == 0) return UNKNOWN_ERROR;
94489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return p->reset();
94589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
94689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
947fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenstatus_t MediaPlayerService::Client::setAudioStreamType(audio_stream_type_t type)
94889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
9493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%d] setAudioStreamType(%d)", mConnId, type);
95089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // TODO: for hardware output, call player instead
95189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock l(mLock);
95289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mAudioOutput != 0) mAudioOutput->setAudioStreamType(type);
95389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
95489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
95589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
95689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayerService::Client::setLooping(int loop)
95789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
9583856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%d] setLooping(%d)", mConnId, loop);
95989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mLoop = loop;
96089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MediaPlayerBase> p = getPlayer();
96189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (p != 0) return p->setLooping(loop);
96289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
96389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
96489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
96589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayerService::Client::setVolume(float leftVolume, float rightVolume)
96689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
9673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%d] setVolume(%f, %f)", mConnId, leftVolume, rightVolume);
968761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
969761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    // for hardware output, call player instead
970761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    sp<MediaPlayerBase> p = getPlayer();
971761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    {
972761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman      Mutex::Autolock l(mLock);
973761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman      if (p != 0 && p->hardwareOutput()) {
974761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman          MediaPlayerHWInterface* hwp =
975761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman                  reinterpret_cast<MediaPlayerHWInterface*>(p.get());
976761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman          return hwp->setVolume(leftVolume, rightVolume);
977761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman      } else {
978761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman          if (mAudioOutput != 0) mAudioOutput->setVolume(leftVolume, rightVolume);
979761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman          return NO_ERROR;
980761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman      }
981761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman    }
982761defc341c5ce9019a42919c441f035f665ec0dJohn Grossman
98389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
98489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
98589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
9862beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurentstatus_t MediaPlayerService::Client::setAuxEffectSendLevel(float level)
9872beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent{
9883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%d] setAuxEffectSendLevel(%f)", mConnId, level);
9892beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    Mutex::Autolock l(mLock);
9902beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    if (mAudioOutput != 0) return mAudioOutput->setAuxEffectSendLevel(level);
9912beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    return NO_ERROR;
9922beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent}
9932beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent
9942beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurentstatus_t MediaPlayerService::Client::attachAuxEffect(int effectId)
9952beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent{
9963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%d] attachAuxEffect(%d)", mConnId, effectId);
9972beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    Mutex::Autolock l(mLock);
9982beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    if (mAudioOutput != 0) return mAudioOutput->attachAuxEffect(effectId);
9992beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    return NO_ERROR;
10002beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent}
10014829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania
10024f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wangstatus_t MediaPlayerService::Client::setParameter(int key, const Parcel &request) {
10033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%d] setParameter(%d)", mConnId, key);
10044f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang    sp<MediaPlayerBase> p = getPlayer();
10054f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang    if (p == 0) return UNKNOWN_ERROR;
10064f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang    return p->setParameter(key, request);
10074f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang}
10084f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang
10094f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wangstatus_t MediaPlayerService::Client::getParameter(int key, Parcel *reply) {
10103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("[%d] getParameter(%d)", mConnId, key);
10114f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang    sp<MediaPlayerBase> p = getPlayer();
10124f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang    if (p == 0) return UNKNOWN_ERROR;
10134f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang    return p->getParameter(key, reply);
10144f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang}
10154f9e47f2c03ce36261c4717cd7e131d7940bb068Gloria Wang
1016c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossmanstatus_t MediaPlayerService::Client::setRetransmitEndpoint(
1017c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        const struct sockaddr_in* endpoint) {
1018c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
1019c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    if (NULL != endpoint) {
1020c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        uint32_t a = ntohl(endpoint->sin_addr.s_addr);
1021c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        uint16_t p = ntohs(endpoint->sin_port);
1022c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        ALOGV("[%d] setRetransmitEndpoint(%u.%u.%u.%u:%hu)", mConnId,
1023c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman                (a >> 24), (a >> 16) & 0xFF, (a >> 8) & 0xFF, (a & 0xFF), p);
1024c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    } else {
1025c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        ALOGV("[%d] setRetransmitEndpoint = <none>", mConnId);
1026c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    }
1027c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
1028c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    sp<MediaPlayerBase> p = getPlayer();
1029c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
1030c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    // Right now, the only valid time to set a retransmit endpoint is before
1031c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    // player selection has been made (since the presence or absence of a
1032c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    // retransmit endpoint is going to determine which player is selected during
1033c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    // setDataSource).
1034c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    if (p != 0) return INVALID_OPERATION;
1035c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
1036c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    if (NULL != endpoint) {
1037c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        mRetransmitEndpoint = *endpoint;
1038c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        mRetransmitEndpointValid = true;
1039c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    } else {
1040c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman        mRetransmitEndpointValid = false;
1041c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    }
1042c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
1043c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman    return NO_ERROR;
1044c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman}
1045c795b64060c3af9d7961fc1371e4ccfa8ee3e450John Grossman
104644a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossmanstatus_t MediaPlayerService::Client::getRetransmitEndpoint(
104744a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman        struct sockaddr_in* endpoint)
104844a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman{
104944a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman    if (NULL == endpoint)
105044a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman        return BAD_VALUE;
105144a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman
105244a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman    sp<MediaPlayerBase> p = getPlayer();
105344a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman
105444a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman    if (p != NULL)
105544a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman        return p->getRetransmitEndpoint(endpoint);
105644a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman
105744a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman    if (!mRetransmitEndpointValid)
105844a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman        return NO_INIT;
105944a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman
106044a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman    *endpoint = mRetransmitEndpoint;
106144a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman
106244a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman    return NO_ERROR;
106344a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman}
106444a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman
1065b483c4724846c0b8d4e82afcbb7c17f671bae81cGloria Wangvoid MediaPlayerService::Client::notify(
1066b483c4724846c0b8d4e82afcbb7c17f671bae81cGloria Wang        void* cookie, int msg, int ext1, int ext2, const Parcel *obj)
106789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
106889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Client* client = static_cast<Client*>(cookie);
1069b8a9825bf0f5c74333b0e4ff5ba7677ac6fd2a25James Dong    if (client == NULL) {
1070b8a9825bf0f5c74333b0e4ff5ba7677ac6fd2a25James Dong        return;
1071b8a9825bf0f5c74333b0e4ff5ba7677ac6fd2a25James Dong    }
1072a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
1073b8a9825bf0f5c74333b0e4ff5ba7677ac6fd2a25James Dong    sp<IMediaPlayerClient> c;
10746b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    {
10756b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        Mutex::Autolock l(client->mLock);
1076b8a9825bf0f5c74333b0e4ff5ba7677ac6fd2a25James Dong        c = client->mClient;
10776b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        if (msg == MEDIA_PLAYBACK_COMPLETE && client->mNextClient != NULL) {
1078cb0b755efc2cd24703f400729994900bf2117f66John Grossman            if (client->mAudioOutput != NULL)
1079cb0b755efc2cd24703f400729994900bf2117f66John Grossman                client->mAudioOutput->switchToNextOutput();
10806b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen            client->mNextClient->start();
10816b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen            client->mNextClient->mClient->notify(MEDIA_INFO, MEDIA_INFO_STARTED_AS_NEXT, 0, obj);
10826b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        }
10836b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    }
10846b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen
1085a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    if (MEDIA_INFO == msg &&
10864829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania        MEDIA_INFO_METADATA_UPDATE == ext1) {
1087a64c8c79af1a15911c55306d83a797fa50969f77niko        const media::Metadata::Type metadata_type = ext2;
10884829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania
10894829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania        if(client->shouldDropMetadata(metadata_type)) {
10904829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania            return;
10914829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania        }
10924829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania
10934829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania        // Update the list of metadata that have changed. getMetadata
10944829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania        // also access mMetadataUpdated and clears it.
10954829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania        client->addNewMetadataUpdate(metadata_type);
1096a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    }
1097b8a9825bf0f5c74333b0e4ff5ba7677ac6fd2a25James Dong
1098b8a9825bf0f5c74333b0e4ff5ba7677ac6fd2a25James Dong    if (c != NULL) {
1099b8a9825bf0f5c74333b0e4ff5ba7677ac6fd2a25James Dong        ALOGV("[%d] notify (%p, %d, %d, %d)", client->mConnId, cookie, msg, ext1, ext2);
1100b8a9825bf0f5c74333b0e4ff5ba7677ac6fd2a25James Dong        c->notify(msg, ext1, ext2, obj);
1101b8a9825bf0f5c74333b0e4ff5ba7677ac6fd2a25James Dong    }
110289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
110389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
11044829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania
1105a64c8c79af1a15911c55306d83a797fa50969f77nikobool MediaPlayerService::Client::shouldDropMetadata(media::Metadata::Type code) const
1106a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania{
11074829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    Mutex::Autolock lock(mLock);
1108a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
11094829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    if (findMetadata(mMetadataDrop, code)) {
1110a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        return true;
1111a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    }
1112a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
11134829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    if (mMetadataAllow.isEmpty() || findMetadata(mMetadataAllow, code)) {
1114a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        return false;
11154829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    } else {
1116a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania        return true;
1117a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania    }
1118a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania}
1119a7e0e8b4c429fc68eb1bd5b5a30f5b91352288f9Nicolas Catania
11204829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania
1121a64c8c79af1a15911c55306d83a797fa50969f77nikovoid MediaPlayerService::Client::addNewMetadataUpdate(media::Metadata::Type metadata_type) {
11224829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    Mutex::Autolock lock(mLock);
11234829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    if (mMetadataUpdated.indexOf(metadata_type) < 0) {
11244829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania        mMetadataUpdated.add(metadata_type);
11254829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania    }
11264829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania}
11274829038419910aa6e75ce8992d45a223452d5c67Nicolas Catania
112889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#if CALLBACK_ANTAGONIZER
112989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectconst int Antagonizer::interval = 10000; // 10 msecs
113089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
113189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectAntagonizer::Antagonizer(notify_callback_f cb, void* client) :
113289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mExit(false), mActive(false), mClient(client), mCb(cb)
113389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
113489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    createThread(callbackThread, this);
113589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
113689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
113789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid Antagonizer::kill()
113889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
113989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(mLock);
114089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mActive = false;
114189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mExit = true;
114289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mCondition.wait(mLock);
114389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
114489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
114589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint Antagonizer::callbackThread(void* user)
114689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
1147b8a805261bf0282e992d3608035e47d05a898710Steve Block    ALOGD("Antagonizer started");
114889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Antagonizer* p = reinterpret_cast<Antagonizer*>(user);
114989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    while (!p->mExit) {
115089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (p->mActive) {
11513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("send event");
115289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            p->mCb(p->mClient, 0, 0, 0);
115389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
115489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        usleep(interval);
115589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
115689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock _l(p->mLock);
115789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    p->mCondition.signal();
1158b8a805261bf0282e992d3608035e47d05a898710Steve Block    ALOGD("Antagonizer stopped");
115989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return 0;
116089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
116189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#endif
116289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
116389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic size_t kDefaultHeapSize = 1024 * 1024; // 1MB
116489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1165e1c3962e268ffc12bfd1bd9ea84da1f135f36960Glenn Kastensp<IMemory> MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat)
116689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
11673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("decode(%s)", url);
116889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MemoryBase> mem;
116989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MediaPlayerBase> player;
117089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
117189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Protect our precious, precious DRMd ringtones by only allowing
117289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // decoding of http, but not filesystem paths or content Uris.
117389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // If the application wants to decode those, it should open a
117489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // filedescriptor for them and use that.
117589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (url != NULL && strncmp(url, "http://", 7) != 0) {
1176b8a805261bf0282e992d3608035e47d05a898710Steve Block        ALOGD("Can't decode %s by path, use filedescriptor instead", url);
117789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return mem;
117889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
117989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
118044a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman    player_type playerType =
118144a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman        MediaPlayerFactory::getPlayerType(NULL /* client */, url);
11823856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("player type = %d", playerType);
118389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
118489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // create the right type of player
118589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<AudioCache> cache = new AudioCache(url);
118644a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman    player = MediaPlayerFactory::createPlayer(playerType, cache.get(), cache->notify);
118789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (player == NULL) goto Exit;
118889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (player->hardwareOutput()) goto Exit;
118989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
119089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache);
119189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
119289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // set data source
119389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (player->setDataSource(url) != NO_ERROR) goto Exit;
119489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
11953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("prepare");
119689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    player->prepareAsync();
119789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
11983856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("wait for prepare");
119989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (cache->wait() != NO_ERROR) goto Exit;
120089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
12013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("start");
120289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    player->start();
120389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
12043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("wait for playback complete");
12059cb839a0fcc98fe4278b39afb8b6d664c04f1673Eric Laurent    cache->wait();
12069cb839a0fcc98fe4278b39afb8b6d664c04f1673Eric Laurent    // in case of error, return what was successfully decoded.
12079cb839a0fcc98fe4278b39afb8b6d664c04f1673Eric Laurent    if (cache->size() == 0) {
12089cb839a0fcc98fe4278b39afb8b6d664c04f1673Eric Laurent        goto Exit;
12099cb839a0fcc98fe4278b39afb8b6d664c04f1673Eric Laurent    }
121089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
121189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mem = new MemoryBase(cache->getHeap(), 0, cache->size());
121289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *pSampleRate = cache->sampleRate();
121389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *pNumChannels = cache->channelCount();
1214e1c3962e268ffc12bfd1bd9ea84da1f135f36960Glenn Kasten    *pFormat = cache->format();
12153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat);
121689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
121789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectExit:
121889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (player != 0) player->reset();
121989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mem;
122089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
122189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1222e1c3962e268ffc12bfd1bd9ea84da1f135f36960Glenn Kastensp<IMemory> MediaPlayerService::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, audio_format_t* pFormat)
122389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
12243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("decode(%d, %lld, %lld)", fd, offset, length);
122589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MemoryBase> mem;
122689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<MediaPlayerBase> player;
122789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
122844a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman    player_type playerType = MediaPlayerFactory::getPlayerType(NULL /* client */,
122944a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman                                                               fd,
123044a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman                                                               offset,
123144a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman                                                               length);
12323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("player type = %d", playerType);
123389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
123489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // create the right type of player
123589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    sp<AudioCache> cache = new AudioCache("decode_fd");
123644a7e42f0310831e6a846d1b6bb40bf3a399bf6dJohn Grossman    player = MediaPlayerFactory::createPlayer(playerType, cache.get(), cache->notify);
123789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (player == NULL) goto Exit;
123889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (player->hardwareOutput()) goto Exit;
123989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
124089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache);
124189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
124289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // set data source
124389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (player->setDataSource(fd, offset, length) != NO_ERROR) goto Exit;
124489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
12453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("prepare");
124689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    player->prepareAsync();
124789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
12483856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("wait for prepare");
124989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (cache->wait() != NO_ERROR) goto Exit;
125089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
12513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("start");
125289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    player->start();
125389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
12543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("wait for playback complete");
12559cb839a0fcc98fe4278b39afb8b6d664c04f1673Eric Laurent    cache->wait();
12569cb839a0fcc98fe4278b39afb8b6d664c04f1673Eric Laurent    // in case of error, return what was successfully decoded.
12579cb839a0fcc98fe4278b39afb8b6d664c04f1673Eric Laurent    if (cache->size() == 0) {
12589cb839a0fcc98fe4278b39afb8b6d664c04f1673Eric Laurent        goto Exit;
12599cb839a0fcc98fe4278b39afb8b6d664c04f1673Eric Laurent    }
126089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
126189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mem = new MemoryBase(cache->getHeap(), 0, cache->size());
126289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *pSampleRate = cache->sampleRate();
126389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *pNumChannels = cache->channelCount();
126489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    *pFormat = cache->format();
12653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat);
126689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
126789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectExit:
126889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (player != 0) player->reset();
126989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    ::close(fd);
127089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mem;
127189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
127289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
127310dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen
127489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#undef LOG_TAG
127589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define LOG_TAG "AudioSink"
1276a514bdb58b5de4986679f72b7204b4764f7a2778Eric LaurentMediaPlayerService::AudioOutput::AudioOutput(int sessionId)
127720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    : mCallback(NULL),
1278a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent      mCallbackCookie(NULL),
12796b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen      mCallbackData(NULL),
12804110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen      mBytesWritten(0),
12811948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent      mSessionId(sessionId),
12821948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent      mFlags(AUDIO_OUTPUT_FLAG_NONE) {
12833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioOutput(%d)", sessionId);
128489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mTrack = 0;
12856b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    mRecycledTrack = 0;
1286fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    mStreamType = AUDIO_STREAM_MUSIC;
128789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mLeftVolume = 1.0;
128889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mRightVolume = 1.0;
12897a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    mPlaybackRatePermille = 1000;
12907a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    mSampleRateHz = 0;
129189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mMsecsPerFrame = 0;
12922beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    mAuxEffectId = 0;
12932beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    mSendLevel = 0.0;
129489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    setMinBufferCount();
129589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
129689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
129789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMediaPlayerService::AudioOutput::~AudioOutput()
129889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
129989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    close();
13006b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    delete mRecycledTrack;
13016b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    delete mCallbackData;
130289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
130389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
130489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid MediaPlayerService::AudioOutput::setMinBufferCount()
130589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
130689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    char value[PROPERTY_VALUE_MAX];
130789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (property_get("ro.kernel.qemu", value, 0)) {
130889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mIsOnEmulator = true;
130989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mMinBufferCount = 12;  // to prevent systematic buffer underrun for emulator
131089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
131189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
131289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
131389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectbool MediaPlayerService::AudioOutput::isOnEmulator()
131489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
131589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    setMinBufferCount();
131689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mIsOnEmulator;
131789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
131889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
131989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectint MediaPlayerService::AudioOutput::getMinBufferCount()
132089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
132189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    setMinBufferCount();
132289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mMinBufferCount;
132389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
132489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
132589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectssize_t MediaPlayerService::AudioOutput::bufferSize() const
132689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
132789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mTrack == 0) return NO_INIT;
132889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mTrack->frameCount() * frameSize();
132989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
133089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
133189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectssize_t MediaPlayerService::AudioOutput::frameCount() const
133289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
133389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mTrack == 0) return NO_INIT;
133489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mTrack->frameCount();
133589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
133689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
133789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectssize_t MediaPlayerService::AudioOutput::channelCount() const
133889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
133989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mTrack == 0) return NO_INIT;
134089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mTrack->channelCount();
134189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
134289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
134389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectssize_t MediaPlayerService::AudioOutput::frameSize() const
134489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
134589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mTrack == 0) return NO_INIT;
134689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mTrack->frameSize();
134789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
134889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
134989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t MediaPlayerService::AudioOutput::latency () const
135089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
1351db354e58e65592777aa17caa47933e14838b8b35Eric Laurent    if (mTrack == 0) return 0;
1352db354e58e65592777aa17caa47933e14838b8b35Eric Laurent    return mTrack->latency();
135389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
135489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
135589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectfloat MediaPlayerService::AudioOutput::msecsPerFrame() const
135689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
135789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mMsecsPerFrame;
135889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
135989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
13604110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissenstatus_t MediaPlayerService::AudioOutput::getPosition(uint32_t *position) const
1361342e9cf388cceb807def720e40e8b0a217f4bcaaEric Laurent{
1362342e9cf388cceb807def720e40e8b0a217f4bcaaEric Laurent    if (mTrack == 0) return NO_INIT;
1363342e9cf388cceb807def720e40e8b0a217f4bcaaEric Laurent    return mTrack->getPosition(position);
1364342e9cf388cceb807def720e40e8b0a217f4bcaaEric Laurent}
1365342e9cf388cceb807def720e40e8b0a217f4bcaaEric Laurent
13664110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissenstatus_t MediaPlayerService::AudioOutput::getFramesWritten(uint32_t *frameswritten) const
13674110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen{
13684110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen    if (mTrack == 0) return NO_INIT;
13694110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen    *frameswritten = mBytesWritten / frameSize();
13704110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen    return OK;
13714110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen}
13724110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen
137320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MediaPlayerService::AudioOutput::open(
1374786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi        uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
1375786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi        audio_format_t format, int bufferCount,
13761948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent        AudioCallback cb, void *cookie,
13771948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent        audio_output_flags_t flags)
137889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
137920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mCallback = cb;
138020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mCallbackCookie = cookie;
138120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
138289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Check argument "bufferCount" against the mininum buffer count
138389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (bufferCount < mMinBufferCount) {
1384b8a805261bf0282e992d3608035e47d05a898710Steve Block        ALOGD("bufferCount (%d) is too small and increased to %d", bufferCount, mMinBufferCount);
138589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        bufferCount = mMinBufferCount;
138689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
138789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
1388786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi    ALOGV("open(%u, %d, 0x%x, %d, %d, %d)", sampleRate, channelCount, channelMask,
1389786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi            format, bufferCount, mSessionId);
139089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int afSampleRate;
139189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int afFrameCount;
13921948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent    uint32_t frameCount;
139389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
139489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (AudioSystem::getOutputFrameCount(&afFrameCount, mStreamType) != NO_ERROR) {
139589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return NO_INIT;
139689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
139789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (AudioSystem::getOutputSamplingRate(&afSampleRate, mStreamType) != NO_ERROR) {
139889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return NO_INIT;
139989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
140089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
140189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    frameCount = (sampleRate*afFrameCount*bufferCount)/afSampleRate;
140220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1403786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi    if (channelMask == CHANNEL_MASK_USE_CHANNEL_ORDER) {
1404ab334fd351ae5a0e18903da123d63e565b536874Glenn Kasten        channelMask = audio_channel_out_mask_from_count(channelCount);
1405786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi        if (0 == channelMask) {
1406786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi            ALOGE("open() error, can\'t derive mask for %d audio channels", channelCount);
1407786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi            return NO_INIT;
1408786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi        }
1409786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi    }
14101948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent
141167295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen    AudioTrack *t;
141267295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen    CallbackData *newcbd = NULL;
141367295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen    if (mCallback != NULL) {
141467295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen        newcbd = new CallbackData(this);
141567295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen        t = new AudioTrack(
141667295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                mStreamType,
141767295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                sampleRate,
141867295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                format,
141967295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                channelMask,
142067295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                frameCount,
142167295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                flags,
142267295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                CallbackWrapper,
142367295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                newcbd,
142467295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                0,  // notification frames
142567295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                mSessionId);
142667295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen    } else {
142767295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen        t = new AudioTrack(
142867295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                mStreamType,
142967295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                sampleRate,
143067295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                format,
143167295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                channelMask,
143267295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                frameCount,
143367295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                flags,
143467295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                NULL,
143567295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                NULL,
143667295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                0,
143767295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                mSessionId);
143867295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen    }
143967295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen
144067295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen    if ((t == 0) || (t->initCheck() != NO_ERROR)) {
144167295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen        ALOGE("Unable to create audio track");
144267295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen        delete t;
144367295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen        delete newcbd;
144467295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen        return NO_INIT;
144567295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen    }
144667295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen
144767295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen
14486b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    if (mRecycledTrack) {
14496b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        // check if the existing track can be reused as-is, or if a new track needs to be created.
14506b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen
14516b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        bool reuse = true;
14526b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        if ((mCallbackData == NULL && mCallback != NULL) ||
14536b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen                (mCallbackData != NULL && mCallback == NULL)) {
14546b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen            // recycled track uses callbacks but the caller wants to use writes, or vice versa
14556b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen            ALOGV("can't chain callback and write");
14566b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen            reuse = false;
14576b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        } else if ((mRecycledTrack->getSampleRate() != sampleRate) ||
14586b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen                (mRecycledTrack->channelCount() != channelCount) ||
145967295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                (mRecycledTrack->frameCount() != t->frameCount())) {
146067295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen            ALOGV("samplerate, channelcount or framecount differ: %d/%d Hz, %d/%d ch, %d/%d frames",
146167295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                  mRecycledTrack->getSampleRate(), sampleRate,
146267295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                  mRecycledTrack->channelCount(), channelCount,
146367295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen                  mRecycledTrack->frameCount(), t->frameCount());
14646b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen            reuse = false;
146567295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen        } else if (flags != mFlags) {
146667295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen            ALOGV("output flags differ %08x/%08x", flags, mFlags);
14671948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent            reuse = false;
14686b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        }
14696b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        if (reuse) {
14706b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen            ALOGV("chaining to next output");
14716b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen            close();
14726b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen            mTrack = mRecycledTrack;
14736b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen            mRecycledTrack = NULL;
14746b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen            if (mCallbackData != NULL) {
14756b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen                mCallbackData->setOutput(this);
14766b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen            }
147767295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen            delete t;
147867295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen            delete newcbd;
14796b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen            return OK;
14806b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        }
14816b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen
14826b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        // if we're not going to reuse the track, unblock and flush it
14836b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        if (mCallbackData != NULL) {
14846b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen            mCallbackData->setOutput(NULL);
14856b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen            mCallbackData->endTrackSwitch();
14866b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        }
14876b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        mRecycledTrack->flush();
14886b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        delete mRecycledTrack;
14896b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        mRecycledTrack = NULL;
14906b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        delete mCallbackData;
14916b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        mCallbackData = NULL;
14926b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        close();
14936b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    }
1494786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi
149567295b543c16ed7c77b67f859d598fe7b4571660Marco Nelissen    mCallbackData = newcbd;
14963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setVolume");
149789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    t->setVolume(mLeftVolume, mRightVolume);
14982beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent
14997a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    mSampleRateHz = sampleRate;
15001948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent    mFlags = flags;
15017a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    mMsecsPerFrame = mPlaybackRatePermille / (float) sampleRate;
150299448608f375a7191c068c3bfd296f204b58a219Marco Nelissen    uint32_t pos;
150399448608f375a7191c068c3bfd296f204b58a219Marco Nelissen    if (t->getPosition(&pos) == OK) {
150499448608f375a7191c068c3bfd296f204b58a219Marco Nelissen        mBytesWritten = uint64_t(pos) * t->frameSize();
150599448608f375a7191c068c3bfd296f204b58a219Marco Nelissen    }
150689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mTrack = t;
15072beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent
15087a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    status_t res = t->setSampleRate(mPlaybackRatePermille * mSampleRateHz / 1000);
15097a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    if (res != NO_ERROR) {
15107a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi        return res;
15117a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    }
15122beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    t->setAuxEffectSendLevel(mSendLevel);
15132beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    return t->attachAuxEffect(mAuxEffectId);;
151489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
151589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
151689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid MediaPlayerService::AudioOutput::start()
151789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
15183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("start");
15196b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    if (mCallbackData != NULL) {
15206b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        mCallbackData->endTrackSwitch();
15216b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    }
152289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mTrack) {
152389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mTrack->setVolume(mLeftVolume, mRightVolume);
15242beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent        mTrack->setAuxEffectSendLevel(mSendLevel);
152589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mTrack->start();
152689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
152789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
152889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
15296b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissenvoid MediaPlayerService::AudioOutput::setNextOutput(const sp<AudioOutput>& nextOutput) {
15306b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    mNextOutput = nextOutput;
15316b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen}
15326b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen
15337ee8ac94bb1a724a481a7cddf10ce63d35df6296Marco Nelissen
15346b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissenvoid MediaPlayerService::AudioOutput::switchToNextOutput() {
15356b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    ALOGV("switchToNextOutput");
15366b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    if (mNextOutput != NULL) {
15376b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        if (mCallbackData != NULL) {
15386b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen            mCallbackData->beginTrackSwitch();
15396b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        }
15406b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        delete mNextOutput->mCallbackData;
15416b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        mNextOutput->mCallbackData = mCallbackData;
15426b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        mCallbackData = NULL;
15436b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        mNextOutput->mRecycledTrack = mTrack;
15446b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        mTrack = NULL;
15456b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        mNextOutput->mSampleRateHz = mSampleRateHz;
15466b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        mNextOutput->mMsecsPerFrame = mMsecsPerFrame;
15474110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen        mNextOutput->mBytesWritten = mBytesWritten;
1548d791e094da5698c787f8db28ca5d5d490c512cf1Marco Nelissen        mNextOutput->mFlags = mFlags;
15496b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    }
15506b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen}
15517ee8ac94bb1a724a481a7cddf10ce63d35df6296Marco Nelissen
155289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectssize_t MediaPlayerService::AudioOutput::write(const void* buffer, size_t size)
155389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
155420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    LOG_FATAL_IF(mCallback != NULL, "Don't call write if supplying a callback.");
155520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    //ALOGV("write(%p, %u)", buffer, size);
155710dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen    if (mTrack) {
155810dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen        ssize_t ret = mTrack->write(buffer, size);
15594110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen        mBytesWritten += ret;
156010dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen        return ret;
156110dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen    }
156289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_INIT;
156389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
156489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
156589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid MediaPlayerService::AudioOutput::stop()
156689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
15673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("stop");
156889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mTrack) mTrack->stop();
156989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
157089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
157189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid MediaPlayerService::AudioOutput::flush()
157289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
15733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("flush");
157489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mTrack) mTrack->flush();
157589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
157689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
157789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid MediaPlayerService::AudioOutput::pause()
157889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
15793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("pause");
158089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mTrack) mTrack->pause();
158189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
158289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
158389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid MediaPlayerService::AudioOutput::close()
158489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
15853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("close");
158689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    delete mTrack;
158789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mTrack = 0;
158889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
158989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
159089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid MediaPlayerService::AudioOutput::setVolume(float left, float right)
159189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
15923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setVolume(%f, %f)", left, right);
159389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mLeftVolume = left;
159489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mRightVolume = right;
159589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mTrack) {
159689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mTrack->setVolume(left, right);
159789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
159889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
159989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
16007a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivistatus_t MediaPlayerService::AudioOutput::setPlaybackRatePermille(int32_t ratePermille)
16017a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi{
16027a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    ALOGV("setPlaybackRatePermille(%d)", ratePermille);
16037a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    status_t res = NO_ERROR;
16047a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    if (mTrack) {
16057a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi        res = mTrack->setSampleRate(ratePermille * mSampleRateHz / 1000);
16067a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    } else {
16077a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi        res = NO_INIT;
16087a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    }
16097a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    mPlaybackRatePermille = ratePermille;
16107a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    if (mSampleRateHz != 0) {
16117a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi        mMsecsPerFrame = mPlaybackRatePermille / (float) mSampleRateHz;
16127a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    }
16137a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi    return res;
16147a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi}
16157a8b0ed6419e57dd8b41d3806893d63d3df91aabJean-Michel Trivi
16162beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurentstatus_t MediaPlayerService::AudioOutput::setAuxEffectSendLevel(float level)
16172beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent{
16183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("setAuxEffectSendLevel(%f)", level);
16192beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    mSendLevel = level;
16202beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    if (mTrack) {
16212beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent        return mTrack->setAuxEffectSendLevel(level);
16222beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    }
16232beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    return NO_ERROR;
16242beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent}
16252beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent
16262beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurentstatus_t MediaPlayerService::AudioOutput::attachAuxEffect(int effectId)
16272beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent{
16283856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("attachAuxEffect(%d)", effectId);
16292beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    mAuxEffectId = effectId;
16302beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    if (mTrack) {
16312beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent        return mTrack->attachAuxEffect(effectId);
16322beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    }
16332beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    return NO_ERROR;
16342beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent}
16352beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent
163620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// static
163720111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaPlayerService::AudioOutput::CallbackWrapper(
1638d217a8c4632b3e3065f8c2a26b9ce4dc4c97171fGlenn Kasten        int event, void *cookie, void *info) {
16393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    //ALOGV("callbackwrapper");
164020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (event != AudioTrack::EVENT_MORE_DATA) {
164120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return;
164220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
164320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16446b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    CallbackData *data = (CallbackData*)cookie;
16456b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    data->lock();
16466b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    AudioOutput *me = data->getOutput();
164720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info;
16486b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    if (me == NULL) {
16496b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        // no output set, likely because the track was scheduled to be reused
16506b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        // by another player, but the format turned out to be incompatible.
16516b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        data->unlock();
16526b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        buffer->size = 0;
16536b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen        return;
16546b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    }
165520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16567d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    size_t actualSize = (*me->mCallback)(
165720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            me, buffer->raw, buffer->size, me->mCallbackCookie);
16587d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
16596b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    if (actualSize == 0 && buffer->size > 0 && me->mNextOutput == NULL) {
166051c1e0e86a0ad95bf3d890a9a2f51e54b8ef9444Andreas Huber        // We've reached EOS but the audio track is not stopped yet,
166151c1e0e86a0ad95bf3d890a9a2f51e54b8ef9444Andreas Huber        // keep playing silence.
166251c1e0e86a0ad95bf3d890a9a2f51e54b8ef9444Andreas Huber
166351c1e0e86a0ad95bf3d890a9a2f51e54b8ef9444Andreas Huber        memset(buffer->raw, 0, buffer->size);
166451c1e0e86a0ad95bf3d890a9a2f51e54b8ef9444Andreas Huber        actualSize = buffer->size;
166551c1e0e86a0ad95bf3d890a9a2f51e54b8ef9444Andreas Huber    }
16662e8ffaf95bd35358ecd14ddf00cddaf3abefe0a9Andreas Huber
166751c1e0e86a0ad95bf3d890a9a2f51e54b8ef9444Andreas Huber    buffer->size = actualSize;
16686b74d671a1321a6ecc4a40b6c87beedfecc1ec44Marco Nelissen    data->unlock();
166920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
167020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16714110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissenint MediaPlayerService::AudioOutput::getSessionId() const
16728c563ed9ca8a863a66965330b5d14bb4b4ab59d4Eric Laurent{
16738c563ed9ca8a863a66965330b5d14bb4b4ab59d4Eric Laurent    return mSessionId;
16748c563ed9ca8a863a66965330b5d14bb4b4ab59d4Eric Laurent}
16758c563ed9ca8a863a66965330b5d14bb4b4ab59d4Eric Laurent
167689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#undef LOG_TAG
167789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define LOG_TAG "AudioCache"
167889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMediaPlayerService::AudioCache::AudioCache(const char* name) :
167989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mChannelCount(0), mFrameCount(1024), mSampleRate(0), mSize(0),
168089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mError(NO_ERROR), mCommandComplete(false)
168189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
168289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // create ashmem heap
168389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mHeap = new MemoryHeapBase(kDefaultHeapSize, 0, name);
168489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
168589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
168689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectuint32_t MediaPlayerService::AudioCache::latency () const
168789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
168889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return 0;
168989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
169089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
169189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectfloat MediaPlayerService::AudioCache::msecsPerFrame() const
169289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
169389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mMsecsPerFrame;
169489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
169589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
16964110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissenstatus_t MediaPlayerService::AudioCache::getPosition(uint32_t *position) const
1697342e9cf388cceb807def720e40e8b0a217f4bcaaEric Laurent{
1698342e9cf388cceb807def720e40e8b0a217f4bcaaEric Laurent    if (position == 0) return BAD_VALUE;
1699342e9cf388cceb807def720e40e8b0a217f4bcaaEric Laurent    *position = mSize;
1700342e9cf388cceb807def720e40e8b0a217f4bcaaEric Laurent    return NO_ERROR;
1701342e9cf388cceb807def720e40e8b0a217f4bcaaEric Laurent}
1702342e9cf388cceb807def720e40e8b0a217f4bcaaEric Laurent
17034110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissenstatus_t MediaPlayerService::AudioCache::getFramesWritten(uint32_t *written) const
17044110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen{
17054110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen    if (written == 0) return BAD_VALUE;
17064110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen    *written = mSize;
17074110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen    return NO_ERROR;
17084110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen}
17094110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissen
17107d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber////////////////////////////////////////////////////////////////////////////////
17117d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
17127d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huberstruct CallbackThread : public Thread {
17137d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    CallbackThread(const wp<MediaPlayerBase::AudioSink> &sink,
17147d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber                   MediaPlayerBase::AudioSink::AudioCallback cb,
17157d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber                   void *cookie);
17167d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
17177d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huberprotected:
17187d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    virtual ~CallbackThread();
17197d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
17207d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    virtual bool threadLoop();
17217d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
17227d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huberprivate:
17237d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    wp<MediaPlayerBase::AudioSink> mSink;
17247d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    MediaPlayerBase::AudioSink::AudioCallback mCallback;
17257d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    void *mCookie;
17267d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    void *mBuffer;
17277d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    size_t mBufferSize;
17287d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
17297d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    CallbackThread(const CallbackThread &);
17307d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    CallbackThread &operator=(const CallbackThread &);
17317d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber};
17327d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
17337d5b8a70c28c0d5746a600467b2887822dbff88eAndreas HuberCallbackThread::CallbackThread(
17347d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber        const wp<MediaPlayerBase::AudioSink> &sink,
17357d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber        MediaPlayerBase::AudioSink::AudioCallback cb,
17367d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber        void *cookie)
17377d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    : mSink(sink),
17387d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber      mCallback(cb),
17397d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber      mCookie(cookie),
17407d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber      mBuffer(NULL),
17417d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber      mBufferSize(0) {
17427d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber}
17437d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
17447d5b8a70c28c0d5746a600467b2887822dbff88eAndreas HuberCallbackThread::~CallbackThread() {
17457d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    if (mBuffer) {
17467d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber        free(mBuffer);
17477d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber        mBuffer = NULL;
17487d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    }
17497d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber}
17507d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
17517d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huberbool CallbackThread::threadLoop() {
17527d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    sp<MediaPlayerBase::AudioSink> sink = mSink.promote();
17537d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    if (sink == NULL) {
17547d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber        return false;
17557d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    }
17567d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
17577d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    if (mBuffer == NULL) {
17587d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber        mBufferSize = sink->bufferSize();
17597d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber        mBuffer = malloc(mBufferSize);
17607d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    }
17617d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
17627d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    size_t actualSize =
17637d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber        (*mCallback)(sink.get(), mBuffer, mBufferSize, mCookie);
17647d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
17657d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    if (actualSize > 0) {
17667d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber        sink->write(mBuffer, actualSize);
17677d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    }
17687d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
17697d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    return true;
17707d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber}
17717d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
17727d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber////////////////////////////////////////////////////////////////////////////////
17737d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
177420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t MediaPlayerService::AudioCache::open(
1775786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi        uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
1776786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi        audio_format_t format, int bufferCount,
17771948eb3ea6eee336e8cdab9b0c693f93f5f19993Eric Laurent        AudioCallback cb, void *cookie, audio_output_flags_t flags)
177889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
1779786618ffe881aceb64d65a6a2e2d76ede6e01ec0Jean-Michel Trivi    ALOGV("open(%u, %d, 0x%x, %d, %d)", sampleRate, channelCount, channelMask, format, bufferCount);
17808eb8011120a68a86199b9960cf1ae91a6ddc7e6dDave Sparks    if (mHeap->getHeapID() < 0) {
17818eb8011120a68a86199b9960cf1ae91a6ddc7e6dDave Sparks        return NO_INIT;
17828eb8011120a68a86199b9960cf1ae91a6ddc7e6dDave Sparks    }
178320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
178489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mSampleRate = sampleRate;
178589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mChannelCount = (uint16_t)channelCount;
1786e1c3962e268ffc12bfd1bd9ea84da1f135f36960Glenn Kasten    mFormat = format;
178789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mMsecsPerFrame = 1.e3 / (float) sampleRate;
17887d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
17897d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    if (cb != NULL) {
17907d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber        mCallbackThread = new CallbackThread(this, cb, cookie);
17917d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    }
179289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return NO_ERROR;
179389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
179489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
17957d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Hubervoid MediaPlayerService::AudioCache::start() {
17967d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    if (mCallbackThread != NULL) {
17977d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber        mCallbackThread->run("AudioCache callback");
17987d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    }
17997d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber}
18007d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
18017d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Hubervoid MediaPlayerService::AudioCache::stop() {
18027d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    if (mCallbackThread != NULL) {
18037d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber        mCallbackThread->requestExitAndWait();
18047d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber    }
18057d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber}
18067d5b8a70c28c0d5746a600467b2887822dbff88eAndreas Huber
180789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectssize_t MediaPlayerService::AudioCache::write(const void* buffer, size_t size)
180889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
18093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("write(%p, %u)", buffer, size);
181089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if ((buffer == 0) || (size == 0)) return size;
181189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
181289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint8_t* p = static_cast<uint8_t*>(mHeap->getBase());
181389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (p == NULL) return NO_INIT;
181489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    p += mSize;
18153856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("memcpy(%p, %p, %u)", p, buffer, size);
181689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mSize + size > mHeap->getSize()) {
181729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Heap size overflow! req size: %d, max size: %d", (mSize + size), mHeap->getSize());
181889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        size = mHeap->getSize() - mSize;
181989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
182089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    memcpy(p, buffer, size);
182189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mSize += size;
182289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return size;
182389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
182489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
182589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// call with lock held
182689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaPlayerService::AudioCache::wait()
182789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
182889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Mutex::Autolock lock(mLock);
18294bbc0ba371c52951191eff1cba7c1ea5d27ee976Dave Sparks    while (!mCommandComplete) {
183089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        mSignal.wait(mLock);
183189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
183289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    mCommandComplete = false;
183389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
183489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (mError == NO_ERROR) {
18353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("wait - success");
183689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else {
18373856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("wait - error");
183889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
183989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return mError;
184089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
184189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1842b483c4724846c0b8d4e82afcbb7c17f671bae81cGloria Wangvoid MediaPlayerService::AudioCache::notify(
1843b483c4724846c0b8d4e82afcbb7c17f671bae81cGloria Wang        void* cookie, int msg, int ext1, int ext2, const Parcel *obj)
184489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{
18453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("notify(%p, %d, %d, %d)", cookie, msg, ext1, ext2);
184689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    AudioCache* p = static_cast<AudioCache*>(cookie);
184789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
184889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // ignore buffering messages
18498eb8011120a68a86199b9960cf1ae91a6ddc7e6dDave Sparks    switch (msg)
18508eb8011120a68a86199b9960cf1ae91a6ddc7e6dDave Sparks    {
18518eb8011120a68a86199b9960cf1ae91a6ddc7e6dDave Sparks    case MEDIA_ERROR:
185229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Error %d, %d occurred", ext1, ext2);
185389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        p->mError = ext1;
18548eb8011120a68a86199b9960cf1ae91a6ddc7e6dDave Sparks        break;
18558eb8011120a68a86199b9960cf1ae91a6ddc7e6dDave Sparks    case MEDIA_PREPARED:
18563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("prepared");
18578eb8011120a68a86199b9960cf1ae91a6ddc7e6dDave Sparks        break;
18588eb8011120a68a86199b9960cf1ae91a6ddc7e6dDave Sparks    case MEDIA_PLAYBACK_COMPLETE:
18593856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("playback complete");
18608eb8011120a68a86199b9960cf1ae91a6ddc7e6dDave Sparks        break;
18618eb8011120a68a86199b9960cf1ae91a6ddc7e6dDave Sparks    default:
18623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("ignored");
18638eb8011120a68a86199b9960cf1ae91a6ddc7e6dDave Sparks        return;
186489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
186589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
186689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // wake up thread
1867fe4c6f01646de47d41bbe3aa6d17c6a0daa2b730Dave Sparks    Mutex::Autolock lock(p->mLock);
186889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    p->mCommandComplete = true;
186989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    p->mSignal.signal();
187089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
187189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
18724110c101c3d0dd8dbc44c8d2d0edd3e2e7d6652fMarco Nelissenint MediaPlayerService::AudioCache::getSessionId() const
18738c563ed9ca8a863a66965330b5d14bb4b4ab59d4Eric Laurent{
18748c563ed9ca8a863a66965330b5d14bb4b4ab59d4Eric Laurent    return 0;
18758c563ed9ca8a863a66965330b5d14bb4b4ab59d4Eric Laurent}
18768c563ed9ca8a863a66965330b5d14bb4b4ab59d4Eric Laurent
18777cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wangvoid MediaPlayerService::addBatteryData(uint32_t params)
18787cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang{
18797cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    Mutex::Autolock lock(mLock);
18809ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
18819ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    int32_t time = systemTime() / 1000000L;
18829ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
18839ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    // change audio output devices. This notification comes from AudioFlinger
18849ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    if ((params & kBatteryDataSpeakerOn)
18859ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            || (params & kBatteryDataOtherAudioDeviceOn)) {
18869ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
18879ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        int deviceOn[NUM_AUDIO_DEVICES];
18889ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
18899ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            deviceOn[i] = 0;
18909ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        }
18919ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
18929ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        if ((params & kBatteryDataSpeakerOn)
18939ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                && (params & kBatteryDataOtherAudioDeviceOn)) {
18949ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            deviceOn[SPEAKER_AND_OTHER] = 1;
18959ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        } else if (params & kBatteryDataSpeakerOn) {
18969ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            deviceOn[SPEAKER] = 1;
18979ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        } else {
18989ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            deviceOn[OTHER_AUDIO_DEVICE] = 1;
18999ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        }
19009ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
19019ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
19029ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            if (mBatteryAudio.deviceOn[i] != deviceOn[i]){
19039ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
19049ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                if (mBatteryAudio.refCount > 0) { // if playing audio
19059ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                    if (!deviceOn[i]) {
19069ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                        mBatteryAudio.lastTime[i] += time;
19079ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                        mBatteryAudio.totalTime[i] += mBatteryAudio.lastTime[i];
19089ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                        mBatteryAudio.lastTime[i] = 0;
19099ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                    } else {
19109ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                        mBatteryAudio.lastTime[i] = 0 - time;
19119ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                    }
19129ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                }
19139ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
19149ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                mBatteryAudio.deviceOn[i] = deviceOn[i];
19159ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            }
19169ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        }
19179ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        return;
19189ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    }
19199ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
19209ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    // an sudio stream is started
19219ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    if (params & kBatteryDataAudioFlingerStart) {
19229ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        // record the start time only if currently no other audio
19239ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        // is being played
19249ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        if (mBatteryAudio.refCount == 0) {
19259ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
19269ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                if (mBatteryAudio.deviceOn[i]) {
19279ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                    mBatteryAudio.lastTime[i] -= time;
19289ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                }
19299ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            }
19309ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        }
19319ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
19329ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        mBatteryAudio.refCount ++;
19339ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        return;
19349ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
19359ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    } else if (params & kBatteryDataAudioFlingerStop) {
19369ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        if (mBatteryAudio.refCount <= 0) {
19375ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("Battery track warning: refCount is <= 0");
19389ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            return;
19399ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        }
19409ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
19419ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        // record the stop time only if currently this is the only
19429ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        // audio being played
19439ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        if (mBatteryAudio.refCount == 1) {
19449ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
19459ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                if (mBatteryAudio.deviceOn[i]) {
19469ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                    mBatteryAudio.lastTime[i] += time;
19479ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                    mBatteryAudio.totalTime[i] += mBatteryAudio.lastTime[i];
19489ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                    mBatteryAudio.lastTime[i] = 0;
19499ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                }
19509ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            }
19519ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        }
19529ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
19539ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        mBatteryAudio.refCount --;
19549ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        return;
19559ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    }
19569ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
19577cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    int uid = IPCThreadState::self()->getCallingUid();
19587cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    if (uid == AID_MEDIA) {
19597cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        return;
19607cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    }
19617cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    int index = mBatteryData.indexOfKey(uid);
19627cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
19637cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    if (index < 0) { // create a new entry for this UID
19647cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        BatteryUsageInfo info;
19657cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        info.audioTotalTime = 0;
19667cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        info.videoTotalTime = 0;
19677cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        info.audioLastTime = 0;
19687cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        info.videoLastTime = 0;
19697cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        info.refCount = 0;
19707cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
19719ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        if (mBatteryData.add(uid, info) == NO_MEMORY) {
197229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Battery track error: no memory for new app");
19739ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            return;
19749ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        }
19757cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    }
19767cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
19777cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    BatteryUsageInfo &info = mBatteryData.editValueFor(uid);
19787cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
19797cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    if (params & kBatteryDataCodecStarted) {
19807cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        if (params & kBatteryDataTrackAudio) {
19817cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            info.audioLastTime -= time;
19827cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            info.refCount ++;
19837cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        }
19847cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        if (params & kBatteryDataTrackVideo) {
19857cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            info.videoLastTime -= time;
19867cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            info.refCount ++;
19877cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        }
19887cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    } else {
19897cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        if (info.refCount == 0) {
19905ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("Battery track warning: refCount is already 0");
19917cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            return;
19927cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        } else if (info.refCount < 0) {
199329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Battery track error: refCount < 0");
19947cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            mBatteryData.removeItem(uid);
19957cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            return;
19967cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        }
19977cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
19987cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        if (params & kBatteryDataTrackAudio) {
19997cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            info.audioLastTime += time;
20007cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            info.refCount --;
20017cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        }
20027cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        if (params & kBatteryDataTrackVideo) {
20037cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            info.videoLastTime += time;
20047cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            info.refCount --;
20057cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        }
20067cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
20077cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        // no stream is being played by this UID
20087cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        if (info.refCount == 0) {
20097cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            info.audioTotalTime += info.audioLastTime;
20107cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            info.audioLastTime = 0;
20117cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            info.videoTotalTime += info.videoLastTime;
20127cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            info.videoLastTime = 0;
20137cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        }
20147cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    }
20157cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang}
20167cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
20177cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wangstatus_t MediaPlayerService::pullBatteryData(Parcel* reply) {
20187cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    Mutex::Autolock lock(mLock);
20199ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
20209ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    // audio output devices usage
20219ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    int32_t time = systemTime() / 1000000L; //in ms
20229ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    int32_t totalTime;
20239ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
20249ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    for (int i = 0; i < NUM_AUDIO_DEVICES; i++) {
20259ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        totalTime = mBatteryAudio.totalTime[i];
20269ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
20279ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        if (mBatteryAudio.deviceOn[i]
20289ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang            && (mBatteryAudio.lastTime[i] != 0)) {
20299ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                int32_t tmpTime = mBatteryAudio.lastTime[i] + time;
20309ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang                totalTime += tmpTime;
20319ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        }
20329ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
20339ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        reply->writeInt32(totalTime);
20349ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        // reset the total time
20359ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang        mBatteryAudio.totalTime[i] = 0;
20369ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang   }
20379ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang
20389ee159b79022b2e1a050acb3890ce948e99e9ccbGloria Wang    // codec usage
20397cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    BatteryUsageInfo info;
20407cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    int size = mBatteryData.size();
20417cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
20427cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    reply->writeInt32(size);
20437cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    int i = 0;
20447cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
20457cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    while (i < size) {
20467cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        info = mBatteryData.valueAt(i);
20477cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
20487cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        reply->writeInt32(mBatteryData.keyAt(i)); //UID
20497cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        reply->writeInt32(info.audioTotalTime);
20507cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        reply->writeInt32(info.videoTotalTime);
20517cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
20527cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        info.audioTotalTime = 0;
20537cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        info.videoTotalTime = 0;
20547cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang
20557cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        // remove the UID entry where no stream is being played
20567cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        if (info.refCount <= 0) {
20577cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            mBatteryData.removeItemsAt(i);
20587cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            size --;
20597cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang            i --;
20607cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        }
20617cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang        i++;
20627cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    }
20637cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang    return NO_ERROR;
20647cf180c9bff69e5cc4a2f4e53b432db45ebbebabGloria Wang}
2065a64c8c79af1a15911c55306d83a797fa50969f77niko} // namespace android
2066