1fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park/* 2fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park * Copyright (C) 2017 The Android Open Source Project 3fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park * 4fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park * Licensed under the Apache License, Version 2.0 (the "License"); 5fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park * you may not use this file except in compliance with the License. 6fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park * You may obtain a copy of the License at 7fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park * 8fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park * http://www.apache.org/licenses/LICENSE-2.0 9fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park * 10fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park * Unless required by applicable law or agreed to in writing, software 11fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park * distributed under the License is distributed on an "AS IS" BASIS, 12fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park * See the License for the specific language governing permissions and 14fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park * limitations under the License. 15fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park */ 16fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Parkpackage com.android.car.test; 17fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 18fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Parkimport android.car.Car; 19fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Parkimport android.car.media.CarAudioManager; 20cfe93105f637c2822da113308f113ed418d0b319Pavel Maltsevimport android.hardware.automotive.vehicle.V2_0.VehiclePropValue; 21cfe93105f637c2822da113308f113ed418d0b319Pavel Maltsevimport android.hardware.automotive.vehicle.V2_0.VehicleProperty; 22cfe93105f637c2822da113308f113ed418d0b319Pavel Maltsevimport android.hardware.automotive.vehicle.V2_0.VehiclePropertyAccess; 23fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Parkimport android.os.SystemClock; 24fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Parkimport android.test.suitebuilder.annotation.MediumTest; 25fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 26fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Parkimport com.android.car.vehiclehal.VehiclePropValueBuilder; 27fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Parkimport com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler; 28fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 29fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Parkimport java.util.concurrent.Semaphore; 30fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Parkimport java.util.concurrent.TimeUnit; 31fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 32fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park@MediumTest 33fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Parkpublic class CarAudioManagerTest extends MockedCarTestBase { 34fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park private final AudioParametersPropertyHandler mAudioParametersPropertyHandler = 35fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park new AudioParametersPropertyHandler(); 36fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park CarAudioManager mCarAudioManager; 37fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 38fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park @Override 39fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park protected synchronized void configureMockedHal() { 40fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park addProperty(VehicleProperty.AUDIO_PARAMETERS, mAudioParametersPropertyHandler) 41fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park .setAccess(VehiclePropertyAccess.READ_WRITE) 42fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park .setConfigString("com.android.test.param1;com.android.test.param2"); 43fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 44fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 45fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park @Override 46fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park protected void setUp() throws Exception { 47fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park super.setUp(); 48fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mCarAudioManager = (CarAudioManager) getCar().getCarManager( 49fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park Car.AUDIO_SERVICE); 50fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park assertNotNull(mCarAudioManager); 51fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 52fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 53fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park public void testAudioParamConfig() throws Exception { 54fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park String[] keys = mCarAudioManager.getParameterKeys(); 55fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park assertNotNull(keys); 56fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park assertEquals(2, keys.length); 57fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park assertEquals("com.android.test.param1", keys[0]); 58fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park assertEquals("com.android.test.param2", keys[1]); 59fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 60fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 61fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park public void testAudioParamSet() throws Exception { 62fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park try { 63fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mCarAudioManager.setParameters(null); 64fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park fail(); 65fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } catch (IllegalArgumentException e) { 66fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park // expected 67fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 68fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 69fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park try { 70fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mCarAudioManager.setParameters("com.android.test.param3=3"); 71fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park fail(); 72fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } catch (IllegalArgumentException e) { 73fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park // expected 74fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 75fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 76fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park final String SET_OK1 = "com.android.test.param1=1"; 77fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mCarAudioManager.setParameters(SET_OK1); 78fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mAudioParametersPropertyHandler.waitForSet(DEFAULT_WAIT_TIMEOUT_MS, SET_OK1); 79fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 80fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park final String SET_OK2 = "com.android.test.param1=1;com.android.test.param2=2"; 81fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mCarAudioManager.setParameters(SET_OK2); 82fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mAudioParametersPropertyHandler.waitForSet(DEFAULT_WAIT_TIMEOUT_MS, SET_OK2); 83fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 84fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 85fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park public void testAudioParamGet() throws Exception { 86fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park try { 87fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mCarAudioManager.getParameters(null); 88fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park fail(); 89fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } catch (IllegalArgumentException e) { 90fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park // expected 91fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 92fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 93fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park try { 94fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mCarAudioManager.getParameters("com.android.test.param3"); 95fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park fail(); 96fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } catch (IllegalArgumentException e) { 97fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park // expected 98fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 99fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 100fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park try { 101fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mCarAudioManager.getParameters("com.android.test.param1;com.android.test.param3"); 102fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park fail(); 103fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } catch (IllegalArgumentException e) { 104fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park // expected 105fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 106fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 107fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park final String GET_RESP1 = "com.android.test.param1=1"; 108fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mAudioParametersPropertyHandler.setValueForGet(GET_RESP1); 109fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park String get1 = mCarAudioManager.getParameters("com.android.test.param1"); 110fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park assertEquals(GET_RESP1, get1); 111fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 112fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park final String GET_RESP2 = "com.android.test.param1=1;com.android.test.param2=2"; 113fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mAudioParametersPropertyHandler.setValueForGet(GET_RESP2); 114fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park String get2 = mCarAudioManager.getParameters( 115fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park "com.android.test.param1;com.android.test.param2"); 116fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park assertEquals(GET_RESP2, get2); 117fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 118fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 119fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park public void testAudioParamChangeListener() throws Exception { 120fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park AudioParamListener listener1 = new AudioParamListener(); 121fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park AudioParamListener listener2 = new AudioParamListener(); 122fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 123fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mCarAudioManager.setOnParameterChangeListener(listener1); 124fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park final String EVENT1 = "com.android.test.param1=10"; 125fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park sendAudioParamChange(EVENT1); 126fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park listener1.waitForChange(DEFAULT_WAIT_TIMEOUT_MS, EVENT1); 127fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 128fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mCarAudioManager.setOnParameterChangeListener(listener2); 129fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park listener1.clearParameter(); 130fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park final String EVENT2 = "com.android.test.param1=20;com.android.test.param2=10"; 131fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park sendAudioParamChange(EVENT2); 132fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park listener2.waitForChange(DEFAULT_WAIT_TIMEOUT_MS, EVENT2); 133fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park listener1.assertParameter(null); 134fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 135fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mCarAudioManager.setOnParameterChangeListener(null); 136fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park listener2.clearParameter(); 137fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park sendAudioParamChange(EVENT1); 138fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park Thread.sleep(200); 139fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park listener1.assertParameter(null); 140fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park listener2.assertParameter(null); 141fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 142fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 143fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park private void sendAudioParamChange(String params) { 144fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park getMockedVehicleHal().injectEvent( 145fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park VehiclePropValueBuilder.newBuilder(VehicleProperty.AUDIO_PARAMETERS) 146fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park .setTimestamp(SystemClock.elapsedRealtimeNanos()) 147fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park .setStringValue(params) 148fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park .build()); 149fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 150fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 151fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park static class AudioParametersPropertyHandler implements VehicleHalPropertyHandler { 152fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park private final Semaphore mSetWaitSemaphore = new Semaphore(0); 153fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 154fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park private String mValueSet; 155fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park private String mGetResponse; 156fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 157fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park public void waitForSet(long waitTimeMs, String expected) throws Exception { 158fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mSetWaitSemaphore.tryAcquire(waitTimeMs, TimeUnit.MILLISECONDS); 159fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park synchronized (this) { 160fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park assertEquals(expected, mValueSet); 161fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 162fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 163fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 164fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park public synchronized void setValueForGet(String value) { 165fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mGetResponse = value; 166fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 167fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 168fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park @Override 169fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park public void onPropertySet(VehiclePropValue value) { 170fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park assertEquals(VehicleProperty.AUDIO_PARAMETERS, value.prop); 171fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park String setValue = value.value.stringValue; 172fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park synchronized (this) { 173fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mValueSet = setValue; 174fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 175fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mSetWaitSemaphore.release(); 176fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 177fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 178fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park @Override 179fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park public VehiclePropValue onPropertyGet(VehiclePropValue value) { 180fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park assertEquals(VehicleProperty.AUDIO_PARAMETERS, value.prop); 181fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park String response; 182fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park synchronized (this) { 183fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park response = mGetResponse; 184fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 185fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park return VehiclePropValueBuilder.newBuilder(VehicleProperty.AUDIO_PARAMETERS) 186fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park .setTimestamp(SystemClock.elapsedRealtimeNanos()) 187fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park .setStringValue(mGetResponse) 188fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park .build(); 189fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 190fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 191fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park @Override 192fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park public void onPropertySubscribe(int property, int zones, float sampleRate) { 193fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park assertEquals(VehicleProperty.AUDIO_PARAMETERS, property); 194fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 195fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 196fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park @Override 197fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park public void onPropertyUnsubscribe(int property) { 198fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park assertEquals(VehicleProperty.AUDIO_PARAMETERS, property); 199fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 200fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 201fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 202fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park static class AudioParamListener implements CarAudioManager.OnParameterChangeListener { 203fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park private String mParameter; 204fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park private final Semaphore mChangeWaitSemaphore = new Semaphore(0); 205fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 206fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park @Override 207fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park public void onParameterChange(String parameters) { 208fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mParameter = parameters; 209fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mChangeWaitSemaphore.release(); 210fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 211fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 212fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park public void waitForChange(long waitTimeMs, String expected) throws Exception { 213fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mChangeWaitSemaphore.tryAcquire(waitTimeMs, TimeUnit.MILLISECONDS); 214fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park assertEquals(expected, mParameter); 215fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 216fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 217fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park public void clearParameter() { 218fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park mParameter = null; 219fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 220fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park 221fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park public void assertParameter(String expected) { 222fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park assertEquals(expected, mParameter); 223fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 224fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park } 225fe1a8f14e1ac56f095d29336e0986950d8adfc0cKeun-young Park} 226