1aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park/*
2aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park * Copyright (C) 2015 The Android Open Source Project
3aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park *
4aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park * Licensed under the Apache License, Version 2.0 (the "License");
5aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park * you may not use this file except in compliance with the License.
6aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park * You may obtain a copy of the License at
7aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park *
8aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park *      http://www.apache.org/licenses/LICENSE-2.0
9aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park *
10aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park * Unless required by applicable law or agreed to in writing, software
11aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park * distributed under the License is distributed on an "AS IS" BASIS,
12aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park * See the License for the specific language governing permissions and
14aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park * limitations under the License.
15aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park */
16aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park#define LOG_TAG "VehicleNetworkAudioHelper"
17aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
18aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park#include <VehicleNetwork.h>
19aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park#include <vehicle-internal.h>
20aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park#include <utils/SystemClock.h>
21aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park#include "VehicleNetworkAudioHelper.h"
22aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
23aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park//#define DBG
24aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park#ifdef DBG
25aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park#define LOGD(x...) ALOGD(x)
26aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park#else
27aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park#define LOGD(x...)
28aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park#endif
29aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parknamespace android {
30aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
31aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park// ----------------------------------------------------------------------------
32aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
33aaeffaff85979583b1826db759b5cdb6184559d5Keun-young ParkVehicleNetworkAudioHelper::VehicleNetworkAudioHelper(int64_t timeoutNs)
34aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    : mTimeoutNs(timeoutNs),
35aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park      mListener(NULL),
36aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park      mHasFocusProperty(false) {
37aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park}
38aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
39aaeffaff85979583b1826db759b5cdb6184559d5Keun-young ParkVehicleNetworkAudioHelper::VehicleNetworkAudioHelper(int64_t timeoutNs,
40aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        sp<VehicleNetworkAudioFocusListener> listener)
41aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    : mTimeoutNs(timeoutNs),
42aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park      mListener(listener),
43aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park      mHasFocusProperty(false) {
44aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park}
45aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
46aaeffaff85979583b1826db759b5cdb6184559d5Keun-young ParkVehicleNetworkAudioHelper::~VehicleNetworkAudioHelper() {
47aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    // nothing to do
48aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park}
49aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
50aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkstatus_t VehicleNetworkAudioHelper::init() {
51aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    Mutex::Autolock autoLock(mLock);
52aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    sp<VehicleNetworkListener> listener(this);
53aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    mService = VehicleNetwork::createVehicleNetwork(listener);
54aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    mScratchValueStreamState.prop = VEHICLE_PROPERTY_INTERNAL_AUDIO_STREAM_STATE;
55aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    mScratchValueStreamState.value_type = VEHICLE_VALUE_TYPE_INT32_VEC2;
56aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    mScratchValueStreamState.timestamp = 0;
57aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    mScratchValueFocus.prop = VEHICLE_PROPERTY_AUDIO_FOCUS;
581488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park    mScratchValueFocus.value_type = VEHICLE_VALUE_TYPE_INT32_VEC4;
59aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    mScratchValueFocus.timestamp = 0;
60aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    updatePropertiesLocked();
61aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    return NO_ERROR;
62aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park}
63aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
64aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkvoid VehicleNetworkAudioHelper::updatePropertiesLocked() {
65aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    sp<VehiclePropertiesHolder> holder = mService->listProperties(VEHICLE_PROPERTY_AUDIO_FOCUS);
66aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    if (holder.get() != NULL && holder->getList().size() == 1) {
67aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        mHasFocusProperty = true;
68aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        mService->subscribe(VEHICLE_PROPERTY_AUDIO_FOCUS, 0);
69aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        mService->getProperty(&mScratchValueFocus);
70aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        mAllowedStreams = mScratchValueFocus.value.int32_array[VEHICLE_AUDIO_FOCUS_INDEX_STREAMS];
71aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        ALOGI("initial focus state 0x%x", mAllowedStreams);
72aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    } else {
73aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        ALOGW("No focus property, assume focus always granted");
74aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        mHasFocusProperty = false;
75aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        mAllowedStreams = 0xffffffff;
76aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    }
77aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    for (size_t i = 0; i < mStreamStates.size(); i++) {
78aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        mStreamStates.editItemAt(i).timeoutStartNs = 0;
79aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    }
80aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park}
81aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
82aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkvoid VehicleNetworkAudioHelper::release() {
83aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    Mutex::Autolock autoLock(mLock);
84aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    if (mService.get() == NULL) {
85aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        return;
86aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    }
87aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    mService = NULL;
88aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park}
89aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
90aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkstatic int32_t streamFlagToStreamNumber(int32_t streamFlag) {
91aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    int32_t flag = 0x1;
92aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    for (int32_t i = 0; i < 32; i++) {
93aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        if ((flag & streamFlag) != 0) {
94aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park            return i;
95aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        }
96aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        flag = flag << 1;
97aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    }
98aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    return -1;
99aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park}
100aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
101aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkvoid VehicleNetworkAudioHelper::notifyStreamStarted(int32_t stream) {
102aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    Mutex::Autolock autoLock(mLock);
103aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    if (!mHasFocusProperty) {
104aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        return;
105aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    }
106aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    int32_t streamNumber = streamFlagToStreamNumber(stream);
107aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    if (streamNumber < 0) {
108aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        ALOGE("notifyStreamStarted, wrong stream:0x%x", stream);
109aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        return;
110aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    }
111aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    StreamState& state = getStreamStateLocked(streamNumber);
112aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    if (state.started) {
113aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        return;
114aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    }
115aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    state.started = true;
116aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    state.timeoutStartNs = elapsedRealtimeNano();
117aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    mScratchValueStreamState.value.int32_array[VEHICLE_AUDIO_STREAM_STATE_INDEX_STATE] =
118aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park            VEHICLE_AUDIO_STREAM_STATE_STARTED;
119aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    mScratchValueStreamState.value.int32_array[VEHICLE_AUDIO_STREAM_STATE_INDEX_STREAM] =
120aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park            streamNumber;
121aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    mScratchValueStreamState.timestamp = android::elapsedRealtimeNano();
122aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    mService->setProperty(mScratchValueStreamState);
123aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park}
124aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
125aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkvoid VehicleNetworkAudioHelper::notifyStreamStopped(int32_t stream) {
126aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    Mutex::Autolock autoLock(mLock);
127aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    if (!mHasFocusProperty) {
128aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        return;
129aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    }
130aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    int32_t streamNumber = streamFlagToStreamNumber(stream);
131aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    if (streamNumber < 0) {
132aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        ALOGE("notifyStreamStopped, wrong stream:0x%x", stream);
133aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        return;
134aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    }
135aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    StreamState& state = getStreamStateLocked(streamNumber);
136aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    if (!state.started) {
137aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        return;
138aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    }
139aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    state.started = false;
140aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    state.timeoutStartNs = 0;
141aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    mScratchValueStreamState.value.int32_array[VEHICLE_AUDIO_STREAM_STATE_INDEX_STATE] =
142aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park            VEHICLE_AUDIO_STREAM_STATE_STOPPED;
143aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    mScratchValueStreamState.value.int32_array[VEHICLE_AUDIO_STREAM_STATE_INDEX_STREAM] =
144aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park            streamNumber;
145aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    mScratchValueStreamState.timestamp = android::elapsedRealtimeNano();
146aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    mService->setProperty(mScratchValueStreamState);
147aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park}
148aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
149aaeffaff85979583b1826db759b5cdb6184559d5Keun-young ParkVehicleNetworkAudioHelper::StreamState& VehicleNetworkAudioHelper::getStreamStateLocked(
150aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        int32_t streamNumber) {
1514aeb4bf0c56588be65264c324bbaaa545ad6714cKeun-young Park    if (streamNumber >= (int32_t) mStreamStates.size()) {
152aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        mStreamStates.insertAt(mStreamStates.size(), streamNumber - mStreamStates.size() + 1);
153aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    }
154aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    return mStreamStates.editItemAt(streamNumber);
155aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park}
156aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
157aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkvehicle_network_audio_helper_focus_state VehicleNetworkAudioHelper::getStreamFocusState(
158aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        int32_t stream) {
159aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    Mutex::Autolock autoLock(mLock);
160aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    if ((mAllowedStreams & stream) == stream) {
161aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        return VEHICLE_NETWORK_AUDIO_HELPER_FOCUS_STATE_FOCUS;
162aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    }
163aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    int32_t streamNumber = streamFlagToStreamNumber(stream);
164aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    if (streamNumber < 0) {
165aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        ALOGE("getStreamFocusState, wrong stream:0x%x", stream);
166aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        return VEHICLE_NETWORK_AUDIO_HELPER_FOCUS_STATE_TIMEOUT;
167aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    }
168aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    StreamState& state = getStreamStateLocked(streamNumber);
169aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    if (state.timeoutStartNs == 0) {
170aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        if (state.started) {
171aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park            state.timeoutStartNs = elapsedRealtimeNano();
172aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        }
173aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    } else {
174aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        int64_t now = elapsedRealtimeNano();
175aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        if ((state.timeoutStartNs + mTimeoutNs) < now) {
176aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park            return VEHICLE_NETWORK_AUDIO_HELPER_FOCUS_STATE_TIMEOUT;
177aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        }
178aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    }
179aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    return VEHICLE_NETWORK_AUDIO_HELPER_FOCUS_STATE_NO_FOCUS;
180aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park}
181aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
182aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkbool VehicleNetworkAudioHelper::waitForStreamFocus(int32_t stream, nsecs_t waitTimeNs) {
183aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    LOGD("waitForStreamFocus");
184aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    Mutex::Autolock autoLock(mLock);
185aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    int64_t currentTime = android::elapsedRealtimeNano();
186aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    int64_t finishTime = currentTime + waitTimeNs;
187aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    while (true) {
188aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        if ((stream & mAllowedStreams) == stream) {
189aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park            LOGD("waitForStreamFocus, has focus");
190aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park            return true;
191aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        }
192aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        currentTime = android::elapsedRealtimeNano();
193aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        if (currentTime >= finishTime) {
194aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park            break;
195aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        }
196aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        nsecs_t waitTime = finishTime - currentTime;
197aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        mFocusWait.waitRelative(mLock, waitTime);
198aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    }
199aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    LOGD("waitForStreamFocus, no focus");
200aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    return false;
201aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park}
202aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
203aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkvoid VehicleNetworkAudioHelper::onEvents(sp<VehiclePropValueListHolder>& events) {
204aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    sp<VehicleNetworkAudioFocusListener> listener;
205aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    int32_t allowedStreams;
206aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    bool changed = false;
207aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    do {
208aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        Mutex::Autolock autoLock(mLock);
209aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        if (mService.get() == NULL) { // already released
210aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park            return;
211aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        }
212aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        for (vehicle_prop_value_t* value : events->getList()) {
213aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park            if (value->prop == VEHICLE_PROPERTY_AUDIO_FOCUS) {
214aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park                mAllowedStreams = value->value.int32_array[VEHICLE_AUDIO_FOCUS_INDEX_STREAMS];
215aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park                ALOGI("audio focus change 0x%x", mAllowedStreams);
216aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park                changed = true;
217aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park            }
218aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        }
219aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        listener = mListener;
220aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        allowedStreams = mAllowedStreams;
221aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        if (changed) {
222aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park            mFocusWait.signal();
223aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        }
224aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    } while (false);
225aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    if (listener.get() != NULL && changed) {
226aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        listener->onFocusChange(allowedStreams);
227aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    }
228aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park}
229aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
230aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkvoid VehicleNetworkAudioHelper::onHalError(int32_t /*errorCode*/, int32_t /*property*/,
231aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        int32_t /*operation*/) {
232aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    // not used
233aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park}
234aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
235aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkvoid VehicleNetworkAudioHelper::onHalRestart(bool /*inMocking*/) {
236aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    LOGD("onHalRestart");
237aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    Mutex::Autolock autoLock(mLock);
238aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    if (mService.get() == NULL) { // already released
239aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park        return;
240aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    }
241aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    updatePropertiesLocked();
242aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park    mFocusWait.signal();
243aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park}
244aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park
245aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Park}; // namespace android
246