1a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung/*
2a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung * Copyright (C) 2015 The Android Open Source Project
3a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung *
4a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung * Licensed under the Apache License, Version 2.0 (the "License");
5a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung * you may not use this file except in compliance with the License.
6a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung * You may obtain a copy of the License at
7a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung *
8a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung *      http://www.apache.org/licenses/LICENSE-2.0
9a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung *
10a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung * Unless required by applicable law or agreed to in writing, software
11a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung * distributed under the License is distributed on an "AS IS" BASIS,
12a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung * See the License for the specific language governing permissions and
14a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung * limitations under the License.
15a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung */
161488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Parkpackage com.android.car.test;
17a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
18e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport android.car.test.VehicleHalEmulator.VehicleHalPropertyHandler;
19aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkimport android.content.Context;
20aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkimport android.media.AudioAttributes;
21aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkimport android.media.AudioManager;
22aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkimport android.os.SystemClock;
235672e85bdf82f6a2350afb942dfe17b7c699af87Keun-young Parkimport android.support.car.Car;
24aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkimport android.support.car.media.CarAudioManager;
252906c4461afa9ac0c5865768a3238281e5ecf26dPavel Maltsevimport android.test.suitebuilder.annotation.MediumTest;
26a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
27a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoungimport com.android.car.vehiclenetwork.VehicleNetworkConsts;
281488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Parkimport com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioContextFlag;
29a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoungimport com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioExtFocusFlag;
30a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoungimport com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioFocusIndex;
31a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoungimport com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioFocusRequest;
32a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoungimport com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioFocusState;
33a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoungimport com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleAudioStream;
34a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoungimport com.android.car.vehiclenetwork.VehiclePropConfigUtil;
35a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoungimport com.android.car.vehiclenetwork.VehiclePropValueUtil;
36a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoungimport com.android.car.vehiclenetwork.VehicleNetworkConsts.VehiclePermissionModel;
37a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoungimport com.android.car.vehiclenetwork.VehicleNetworkConsts.VehiclePropAccess;
38a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoungimport com.android.car.vehiclenetwork.VehicleNetworkConsts.VehiclePropChangeMode;
39a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoungimport com.android.car.vehiclenetwork.VehicleNetworkConsts.VehicleValueType;
40a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoungimport com.android.car.vehiclenetwork.VehicleNetworkProto.VehiclePropValue;
41a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
42aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkimport java.util.LinkedList;
43aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkimport java.util.concurrent.Semaphore;
44aaeffaff85979583b1826db759b5cdb6184559d5Keun-young Parkimport java.util.concurrent.TimeUnit;
45a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
462906c4461afa9ac0c5865768a3238281e5ecf26dPavel Maltsev@MediumTest
47a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoungpublic class CarAudioFocusTest extends MockedCarTestBase {
48a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
49a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    private static final long TIMEOUT_MS = 3000;
50a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
51a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    private final VehicleHalPropertyHandler mAudioRoutingPolicyPropertyHandler =
52a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            new VehicleHalPropertyHandler() {
53a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        @Override
54a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        public void onPropertySet(VehiclePropValue value) {
55a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            //TODO
56a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
57a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
58a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        @Override
59a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        public VehiclePropValue onPropertyGet(VehiclePropValue value) {
60a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            fail("cannot get");
61a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            return null;
62a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
63a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
64a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        @Override
650727f9536803bf13e49ff73bd1ed04489b592c56Keun-young Park        public void onPropertySubscribe(int property, float sampleRate, int zones) {
66a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            fail("cannot subscribe");
67a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
68a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
69a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        @Override
70a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        public void onPropertyUnsubscribe(int property) {
71a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            fail("cannot unsubscribe");
72a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
73a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    };
74a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
75a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    private final FocusPropertyHandler mAudioFocusPropertyHandler =
76a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            new FocusPropertyHandler();
77a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
78a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    private final VehicleHalPropertyHandler mAppContextPropertyHandler =
79a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            new VehicleHalPropertyHandler() {
80a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
81a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        @Override
82a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        public void onPropertySet(VehiclePropValue value) {
83a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            // TODO Auto-generated method stub
84a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
85a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
86a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
87a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        @Override
88a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        public VehiclePropValue onPropertyGet(VehiclePropValue value) {
89a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            // TODO Auto-generated method stub
90a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            return null;
91a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
92a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
93a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        @Override
940727f9536803bf13e49ff73bd1ed04489b592c56Keun-young Park        public void onPropertySubscribe(int property, float sampleRate, int zones) {
95a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            // TODO Auto-generated method stub
96a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
97a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
98a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
99a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        @Override
100a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        public void onPropertyUnsubscribe(int property) {
101a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            // TODO Auto-generated method stub
102a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
103a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
104a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    };
105a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
106a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    private final Semaphore mWaitSemaphore = new Semaphore(0);
107a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    private final LinkedList<VehiclePropValue> mEvents = new LinkedList<VehiclePropValue>();
108a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    private AudioManager mAudioManager;
109a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
110a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    @Override
111a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    protected void setUp() throws Exception {
112a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        super.setUp();
113a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // AudioManager should be created in main thread to get focus event. :(
114a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        runOnMainSync(new Runnable() {
115a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            @Override
116a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            public void run() {
117a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
118a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            }
119a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        });
120a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
121a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        getVehicleHalEmulator().addProperty(
122a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehiclePropConfigUtil.getBuilder(
123a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_ROUTING_POLICY,
124a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        VehiclePropAccess.VEHICLE_PROP_ACCESS_WRITE,
125a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        VehiclePropChangeMode.VEHICLE_PROP_CHANGE_MODE_ON_CHANGE,
126a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC2,
127a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        VehiclePermissionModel.VEHICLE_PERMISSION_SYSTEM_APP_ONLY,
128a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        0 /*configFlags*/, 0 /*sampleRateMax*/, 0 /*sampleRateMin*/).build(),
129a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        mAudioRoutingPolicyPropertyHandler);
130a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        getVehicleHalEmulator().addProperty(
131a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehiclePropConfigUtil.getBuilder(
132a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_FOCUS,
133a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        VehiclePropAccess.VEHICLE_PROP_ACCESS_READ_WRITE,
134a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        VehiclePropChangeMode.VEHICLE_PROP_CHANGE_MODE_ON_CHANGE,
1351488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park                        VehicleValueType.VEHICLE_VALUE_TYPE_INT32_VEC4,
136a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        VehiclePermissionModel.VEHICLE_PERMISSION_SYSTEM_APP_ONLY,
137a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        0 /*configFlags*/, 0 /*sampleRateMax*/, 0 /*sampleRateMin*/).build(),
138a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        mAudioFocusPropertyHandler);
139a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        getVehicleHalEmulator().addStaticProperty(
140a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehiclePropConfigUtil.createStaticStringProperty(
141a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_HW_VARIANT),
142a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehiclePropValueUtil.createIntValue(
143a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_HW_VARIANT, 1, 0));
144a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        getVehicleHalEmulator().start();
145a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    }
146a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
147a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    public void testMediaGainFocus() throws Exception {
148a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        //TODO update this to check config
149a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        checkSingleRequestRelease(
150a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.STREAM_MUSIC,
151a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.AUDIOFOCUS_GAIN,
1521488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park                VehicleAudioStream.VEHICLE_AUDIO_STREAM0,
1531488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park                VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG);
154a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    }
155a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
156a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    public void testMediaGainTransientFocus() throws Exception {
157a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        checkSingleRequestRelease(
158a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.STREAM_MUSIC,
159a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT,
1601488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park                VehicleAudioStream.VEHICLE_AUDIO_STREAM0,
1611488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park                VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG);
162a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    }
163a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
164a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    public void testMediaGainTransientMayDuckFocus() throws Exception {
165a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        checkSingleRequestRelease(
166a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.STREAM_MUSIC,
167a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
1681488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park                VehicleAudioStream.VEHICLE_AUDIO_STREAM0,
1691488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park                VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG);
170a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    }
171a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
172a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    public void testAlarmGainTransientFocus() throws Exception {
173a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        checkSingleRequestRelease(
174a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.STREAM_ALARM,
175a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT,
1761488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park                VehicleAudioStream.VEHICLE_AUDIO_STREAM1,
1771488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park                VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_ALARM_FLAG);
178a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    }
179a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
180a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    public void testAlarmGainTransientMayDuckFocus() throws Exception {
181a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        checkSingleRequestRelease(
182a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.STREAM_ALARM,
183a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
1841488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park                VehicleAudioStream.VEHICLE_AUDIO_STREAM1,
1851488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park                VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_ALARM_FLAG);
186a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    }
187a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
188a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    public void testMediaNavFocus() throws Exception {
189a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        //music start
190a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        AudioFocusListener listenerMusic = new AudioFocusListener();
191a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        int res = mAudioManager.requestAudioFocus(listenerMusic,
192a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.STREAM_MUSIC,
193a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.AUDIOFOCUS_GAIN);
194a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
195a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        int[] request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
196a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN, request[0]);
197a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0x1 << VehicleAudioStream.VEHICLE_AUDIO_STREAM0, request[1]);
198a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[2]);
1991488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG, request[3]);
200a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
201a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_GAIN,
202a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                request[1],
203a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_NONE_FLAG);
204a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
205a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // nav guidance start
206a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        AudioFocusListener listenerNav = new AudioFocusListener();
207a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        AudioAttributes navAttrib = (new AudioAttributes.Builder()).
208a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).
209a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
210a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                build();
211a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        res = mAudioManager.requestAudioFocus(listenerNav, navAttrib,
212a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
213a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
214a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN, request[0]);
215a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0x3, request[1]);
216a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[2]);
2171488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG |
2181488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park                VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_NAVIGATION_FLAG, request[3]);
219a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
220a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_GAIN, request[1],
221a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_NONE_FLAG);
222a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
223a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // nav guidance done
224a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioManager.abandonAudioFocus(listenerNav);
225a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
226a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN, request[0]);
227a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0x1 << VehicleAudioStream.VEHICLE_AUDIO_STREAM0, request[1]);
228a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[2]);
2291488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG, request[3]);
230a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
231a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_GAIN, request[1],
232a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_NONE_FLAG);
233a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
234a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // music done
235a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioManager.abandonAudioFocus(listenerMusic);
236a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
237a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_RELEASE, request[0]);
238a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[1]);
239a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[2]);
2401488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(0, request[3]);
241a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
242a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_LOSS, request[1],
243a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_NONE_FLAG);
244a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    }
245a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
246a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    public void testMediaExternalMediaNavFocus() throws Exception {
247a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // android music
248a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        AudioFocusListener listenerMusic = new AudioFocusListener();
249a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        int res = mAudioManager.requestAudioFocus(listenerMusic,
250a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.STREAM_MUSIC,
251a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.AUDIOFOCUS_GAIN);
252a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
253a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        int[] request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
254a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN, request[0]);
255a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0x1 << VehicleAudioStream.VEHICLE_AUDIO_STREAM0, request[1]);
256a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[2]);
2571488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG, request[3]);
258a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
259a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_GAIN,
260a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                request[1],
261a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_NONE_FLAG);
262a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
263a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // car plays external media (=outside Android)
264a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
265a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_LOSS,
266a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                0,
267a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_CAR_PERMANENT_FLAG);
268a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        int focusChange = listenerMusic.waitAndGetFocusChange(TIMEOUT_MS);
269a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(AudioManager.AUDIOFOCUS_LOSS, focusChange);
270a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
271a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // nav guidance start
272a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        AudioFocusListener listenerNav = new AudioFocusListener();
273a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        AudioAttributes navAttrib = (new AudioAttributes.Builder()).
274a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).
275a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
276a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                build();
277a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        res = mAudioManager.requestAudioFocus(listenerNav, navAttrib,
278a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
279a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
280a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN_TRANSIENT_MAY_DUCK,
281a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                request[0]);
282a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0x1 << VehicleAudioStream.VEHICLE_AUDIO_STREAM1, request[1]);
2831488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(0, request[2]);
2841488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_NAVIGATION_FLAG, request[3]);
285a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
286a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_GAIN_TRANSIENT,
287a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                0x1 << VehicleAudioStream.VEHICLE_AUDIO_STREAM1,
288a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_CAR_PERMANENT_FLAG);
289a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
290a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // nav guidance ends
291a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioManager.abandonAudioFocus(listenerNav);
292a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
293a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_RELEASE, request[0]);
294a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[1]);
295a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[2]);
2961488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(0, request[3]);
297a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
298a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_LOSS,
299a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                0,
300a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_CAR_PERMANENT_FLAG);
301a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
302a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // now ends external play
303a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
304a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_LOSS,
305a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                0,
306a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                0);
307a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // music picks up
308a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        listenerMusic.waitForFocus(TIMEOUT_MS, AudioManager.AUDIOFOCUS_GAIN);
309a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
310a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN, request[0]);
311a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0x1 << VehicleAudioStream.VEHICLE_AUDIO_STREAM0, request[1]);
312a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[2]);
3131488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG, request[3]);
314a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
315a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_GAIN,
316a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                request[1],
317a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_NONE_FLAG);
318a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
319a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // now ends music
320a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioManager.abandonAudioFocus(listenerMusic);
321a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
322a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_RELEASE, request[0]);
323a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[1]);
324a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[2]);
3251488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(0, request[3]);
326a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
327a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_LOSS,
328a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                0,
329a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                0);
330a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    }
331a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
332a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    public void testMediaExternalRadioNavMediaFocus() throws Exception {
333a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // android music
334a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        AudioFocusListener listenerMusic = new AudioFocusListener();
335a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        int res = mAudioManager.requestAudioFocus(listenerMusic,
336a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.STREAM_MUSIC,
337a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.AUDIOFOCUS_GAIN);
338a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
339a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        int[] request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
340a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN, request[0]);
341a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0x1 << VehicleAudioStream.VEHICLE_AUDIO_STREAM0, request[1]);
342a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[2]);
3431488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG, request[3]);
344a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
345a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_GAIN,
346a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                request[1],
347a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_NONE_FLAG);
348a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
349a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // android radio
350a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        AudioFocusListener listenerRadio = new AudioFocusListener();
351e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        CarAudioManager carAudioManager = (CarAudioManager) getSupportCar().getCarManager(
3525672e85bdf82f6a2350afb942dfe17b7c699af87Keun-young Park                Car.AUDIO_SERVICE);
3535672e85bdf82f6a2350afb942dfe17b7c699af87Keun-young Park        assertNotNull(carAudioManager);
3545672e85bdf82f6a2350afb942dfe17b7c699af87Keun-young Park        AudioAttributes radioAttributes = carAudioManager.getAudioAttributesForCarUsage(
3555672e85bdf82f6a2350afb942dfe17b7c699af87Keun-young Park                CarAudioManager.CAR_AUDIO_USAGE_RADIO);
356a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        res = mAudioManager.requestAudioFocus(listenerRadio,
357a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                radioAttributes, AudioManager.AUDIOFOCUS_GAIN, 0);
358a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
359a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
360a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN, request[0]);
361a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[1]);
362a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_CAR_PLAY_ONLY_FLAG,
363a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                request[2]);
3641488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        // no android side context for radio
3651488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(0, request[3]);
366a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
367a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_GAIN,
368a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                0,
369a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_CAR_PLAY_ONLY_FLAG);
370a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
371a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // nav guidance start
372a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        AudioFocusListener listenerNav = new AudioFocusListener();
373a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        AudioAttributes navAttrib = (new AudioAttributes.Builder()).
374a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).
375a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
376a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                build();
377a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        res = mAudioManager.requestAudioFocus(listenerNav, navAttrib,
378a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
379a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
380a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN,
381a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                request[0]);
382a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0x1 << VehicleAudioStream.VEHICLE_AUDIO_STREAM1, request[1]);
383a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_CAR_PLAY_ONLY_FLAG,
384a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                request[2]);
3851488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_NAVIGATION_FLAG, request[3]);
386a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
387a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_GAIN,
388a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                0x1 << VehicleAudioStream.VEHICLE_AUDIO_STREAM1,
389a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_CAR_PLAY_ONLY_FLAG);
390a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
391a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // nav guidance ends
392a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioManager.abandonAudioFocus(listenerNav);
393a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
394a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN,
395a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                request[0]);
396a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[1]);
397a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_CAR_PLAY_ONLY_FLAG,
398a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                request[2]);
3991488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(0, request[3]);
400a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
401a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_GAIN,
402a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                0,
403a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_CAR_PLAY_ONLY_FLAG);
404a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
405a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // ends radio. music will get the focus GAIN.
406a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // Music app is supposed to stop and release focus when it has lost focus, but here just
407a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // check if focus is working.
408a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioManager.abandonAudioFocus(listenerRadio);
409a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        listenerMusic.waitForFocus(TIMEOUT_MS, AudioManager.AUDIOFOCUS_GAIN);
410a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
411a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN, request[0]);
412a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0x1 << VehicleAudioStream.VEHICLE_AUDIO_STREAM0, request[1]);
413a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[2]);
4141488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(VehicleAudioContextFlag.VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG, request[3]);
415a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
416a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_GAIN,
417a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                0x1 << VehicleAudioStream.VEHICLE_AUDIO_STREAM0,
418a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                0);
419a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
420a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        // now music release focus.
421a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioManager.abandonAudioFocus(listenerMusic);
422a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
423a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_RELEASE, request[0]);
424a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[1]);
425a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[2]);
4261488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(0, request[3]);
427a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
428a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_LOSS,
429a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                0,
430a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_NONE_FLAG);
431a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    }
432a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
4331488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park    private void checkSingleRequestRelease(int streamType, int androidFocus, int streamNumber,
4341488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park            int context)
435a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            throws Exception {
436a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        AudioFocusListener lister = new AudioFocusListener();
437a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        int res = mAudioManager.requestAudioFocus(lister,
438a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                streamType,
439a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                androidFocus);
440a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
441a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        int[] request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
442a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        int expectedRequest = VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_RELEASE;
443a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        int response = VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_LOSS;
444a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        switch (androidFocus) {
445a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            case AudioManager.AUDIOFOCUS_GAIN:
446a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                expectedRequest = VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN;
447a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                response = VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_GAIN;
448a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                break;
449a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
450a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                expectedRequest =
451a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                    VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN_TRANSIENT;
452a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                response = VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_GAIN_TRANSIENT;
453a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                break;
454a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
455a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                expectedRequest =
456a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                    VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_GAIN_TRANSIENT_MAY_DUCK;
457a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                response = VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_GAIN_TRANSIENT;
458a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                break;
459a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
460a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(expectedRequest, request[0]);
461a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0x1 << streamNumber, request[1]);
462a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[2]);
4631488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(context, request[3]);
464a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
465a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                response,
466a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                request[1],
467a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_NONE_FLAG);
468a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioManager.abandonAudioFocus(lister);
469a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
470a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(VehicleAudioFocusRequest.VEHICLE_AUDIO_FOCUS_REQUEST_RELEASE, request[0]);
471a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[1]);
472a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        assertEquals(0, request[2]);
4731488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        assertEquals(0, request[3]);
474a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        mAudioFocusPropertyHandler.sendAudioFocusState(
475a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_LOSS,
476a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                request[1],
477a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                VehicleAudioExtFocusFlag.VEHICLE_AUDIO_EXT_FOCUS_NONE_FLAG);
478a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    }
479a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
480a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    private class AudioFocusListener implements AudioManager.OnAudioFocusChangeListener {
481a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        private final Semaphore mFocusChangeWait = new Semaphore(0);
482a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        private int mLastFocusChange;
483a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
484a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        public int waitAndGetFocusChange(long timeoutMs) throws Exception {
485a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            if (!mFocusChangeWait.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) {
486a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                fail("timeout waiting for focus change");
487a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            }
488a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            return mLastFocusChange;
489a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
490a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
491a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        public void waitForFocus(long timeoutMs, int expectedFocus) throws Exception {
492a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            while (mLastFocusChange != expectedFocus) {
493a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                if (!mFocusChangeWait.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) {
494a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                    fail("timeout waiting for focus change");
495a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                }
496a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            }
497a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
498a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
499a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        @Override
500a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        public void onAudioFocusChange(int focusChange) {
501a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            mLastFocusChange = focusChange;
502a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            mFocusChangeWait.release();
503a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
504a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    }
505a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
506a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    private class FocusPropertyHandler implements VehicleHalPropertyHandler {
507a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
508a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        private int mState = VehicleAudioFocusState.VEHICLE_AUDIO_FOCUS_STATE_LOSS;
509a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        private int mStreams = 0;
510a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        private int mExtFocus = 0;
511a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        private int mRequest;
512a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        private int mRequestedStreams;
513a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        private int mRequestedExtFocus;
5141488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park        private int mRequestedAudioContexts;
515a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
516a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        private final Semaphore mSetWaitSemaphore = new Semaphore(0);
517a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
518a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        public void sendAudioFocusState(int state, int streams, int extFocus) {
519a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            synchronized (this) {
520a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                mState = state;
521a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                mStreams = streams;
522a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                mExtFocus = extFocus;
523a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            }
5241488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park            int[] values = { state, streams, extFocus, 0 };
525a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            getVehicleHalEmulator().injectEvent(VehiclePropValueUtil.createIntVectorValue(
526a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                    VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_FOCUS, values,
527a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                    SystemClock.elapsedRealtimeNanos()));
528a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
529a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
530a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        public int[] waitForAudioFocusRequest(long timeoutMs) throws Exception {
531a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            if (!mSetWaitSemaphore.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) {
532a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                fail("timeout");
533a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            }
534a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            synchronized (this) {
5351488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park                return new int[] { mRequest, mRequestedStreams, mRequestedExtFocus,
5361488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park                        mRequestedAudioContexts };
537a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            }
538a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
539a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
540a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        @Override
541a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        public void onPropertySet(VehiclePropValue value) {
542a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            assertEquals(VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_FOCUS, value.getProp());
543a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            synchronized (this) {
544a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                mRequest = value.getInt32Values(
545a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        VehicleAudioFocusIndex.VEHICLE_AUDIO_FOCUS_INDEX_FOCUS);
546a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                mRequestedStreams = value.getInt32Values(
547a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        VehicleAudioFocusIndex.VEHICLE_AUDIO_FOCUS_INDEX_STREAMS);
548a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                mRequestedExtFocus = value.getInt32Values(
549a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                        VehicleAudioFocusIndex.VEHICLE_AUDIO_FOCUS_INDEX_EXTERNAL_FOCUS_STATE);
5501488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park                mRequestedAudioContexts = value.getInt32Values(
5511488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park                        VehicleAudioFocusIndex.VEHICLE_AUDIO_FOCUS_INDEX_AUDIO_CONTEXTS);
552a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            }
553a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            mSetWaitSemaphore.release();
554a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
555a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
556a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        @Override
557a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        public VehiclePropValue onPropertyGet(VehiclePropValue value) {
558a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            assertEquals(VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_FOCUS, value.getProp());
559a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            int state, streams, extFocus;
560a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            synchronized (this) {
561a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                state = mState;
562a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                streams = mStreams;
563a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                extFocus = mExtFocus;
564a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            }
5651488ef2171bbc3bf25fc00c424a9979843f5ec6eKeun-young Park            int[] values = { state, streams, extFocus, 0 };
566a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            return VehiclePropValueUtil.createIntVectorValue(
567a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                    VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_FOCUS, values,
568a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung                    SystemClock.elapsedRealtimeNanos());
569a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
570a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
571a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        @Override
5720727f9536803bf13e49ff73bd1ed04489b592c56Keun-young Park        public void onPropertySubscribe(int property, float sampleRate, int zones) {
573a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            assertEquals(VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_FOCUS, property);
574a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
575a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung
576a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        @Override
577a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        public void onPropertyUnsubscribe(int property) {
578a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung            assertEquals(VehicleNetworkConsts.VEHICLE_PROPERTY_AUDIO_FOCUS, property);
579a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung        }
580a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung    }
581a74b9caa2fb6435f1c01c5e8766b89235c4e3d5akeunyoung}
582