From 83ee9019d35529bb1d6ddb10a007b83ff5a2ffb9 Mon Sep 17 00:00:00 2001 From: Ram Periathiruvadi Date: Tue, 18 Jul 2017 19:21:06 -0700 Subject: Unit tests for BluetoothDeviceConnectionPolicy. Bug: b/33078994 Test: runtest -x /BluetoothAutoConnectPolicyTest.java Change-Id: I656a63c64df95c5ea50693bfb841611f84e2000b --- .../car/BluetoothDeviceConnectionPolicy.java | 57 +++- .../src/com/android/car/BluetoothDevicesInfo.java | 4 + tests/carservice_unit_test/Android.mk | 2 +- tests/carservice_unit_test/AndroidManifest.xml | 2 +- .../car/BluetoothAutoConnectPolicyTest.java | 371 +++++++++++++++++++++ 5 files changed, 423 insertions(+), 13 deletions(-) create mode 100644 tests/carservice_unit_test/src/com/android/car/BluetoothAutoConnectPolicyTest.java diff --git a/service/src/com/android/car/BluetoothDeviceConnectionPolicy.java b/service/src/com/android/car/BluetoothDeviceConnectionPolicy.java index e80b843291..4ea0db599e 100644 --- a/service/src/com/android/car/BluetoothDeviceConnectionPolicy.java +++ b/service/src/com/android/car/BluetoothDeviceConnectionPolicy.java @@ -51,6 +51,8 @@ import android.content.IntentFilter; import android.os.RemoteException; import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; + import java.lang.StringBuilder; import java.io.PrintWriter; import java.util.ArrayList; @@ -126,11 +128,12 @@ public class BluetoothDeviceConnectionPolicy { // The Bluetooth profiles that the CarService will try to auto-connect on. private final List mProfilesToConnect; private static final int MAX_CONNECT_RETRIES = 1; - private static final int PROFILE_NOT_AVAILABLE = -1; // Device & Profile currently being connected on private ConnectionParams mConnectionInFlight; + // Allow write to Settings.Secure + private boolean mAllowReadWriteToSettings = true; public static BluetoothDeviceConnectionPolicy create(Context context, CarCabinService carCabinService, CarSensorService carSensorService, @@ -383,7 +386,8 @@ public class BluetoothDeviceConnectionPolicy { * Cleanup state and reinitialize whenever we connect to the PerUserCarService. * This happens in init() and whenever the PerUserCarService is restarted on User Switch Events */ - private class UserServiceConnectionCallback implements PerUserCarServiceHelper.ServiceCallback { + @VisibleForTesting + class UserServiceConnectionCallback implements PerUserCarServiceHelper.ServiceCallback { @Override public void onServiceConnected(ICarUserService carUserService) { if (mCarUserServiceAccessLock != null) { @@ -573,7 +577,8 @@ public class BluetoothDeviceConnectionPolicy { * Upon receiving the event that is of interest, initiate a connection attempt by calling * the policy {@link BluetoothDeviceConnectionPolicy} */ - private class CarPropertyListener extends ICarPropertyEventListener.Stub { + @VisibleForTesting + class CarPropertyListener extends ICarPropertyEventListener.Stub { @Override public void onEvent(CarPropertyEvent event) throws RemoteException { if (DBG) { @@ -658,7 +663,9 @@ public class BluetoothDeviceConnectionPolicy { mProfileToConnectableDevicesMap = null; mConnectionInFlight = null; if (mBluetoothBroadcastReceiver != null) { - mContext.unregisterReceiver(mBluetoothBroadcastReceiver); + if (mContext != null) { + mContext.unregisterReceiver(mBluetoothBroadcastReceiver); + } mBluetoothBroadcastReceiver = null; } } @@ -695,6 +702,26 @@ public class BluetoothDeviceConnectionPolicy { } } + @VisibleForTesting + BroadcastReceiver getBluetoothBroadcastReceiver() { + return mBluetoothBroadcastReceiver; + } + + @VisibleForTesting + UserServiceConnectionCallback getServiceCallback() { + return mServiceCallback; + } + + @VisibleForTesting + CarPropertyListener getCarPropertyListener() { + return mCabinEventListener; + } + + @VisibleForTesting + synchronized void setAllowReadWriteToSettings(boolean allowWrite) { + mAllowReadWriteToSettings = allowWrite; + } + /** * Resets the {@link #mProfileToConnectableDevicesMap} to a clean and empty slate. */ @@ -792,7 +819,6 @@ public class BluetoothDeviceConnectionPolicy { Log.w(TAG, "Bluetooth Adapter null"); return; } - if (mBluetoothAdapter.isEnabled()) { if (isDeviceMapEmpty()) { if (DBG) { @@ -1050,7 +1076,7 @@ public class BluetoothDeviceConnectionPolicy { BluetoothDevice deviceThatConnected = params.getBluetoothDevice(); if (DBG) { Log.d(TAG, "Profile: " + profileToUpdate + " Connected: " + didConnect + " on " - + deviceThatConnected.getName()); + + deviceThatConnected); } // If the connection update is on a different profile or device (a very rare possibility), @@ -1066,9 +1092,9 @@ public class BluetoothDeviceConnectionPolicy { if (mConnectionInFlight != null && mConnectionInFlight.getBluetoothDevice() != null) { if (deviceThatConnected.equals(mConnectionInFlight.getBluetoothDevice()) == false) { - Log.d(TAG, "Updating device: " + deviceThatConnected.getName() + Log.d(TAG, "Updating device: " + deviceThatConnected + " different from connection in flight: " - + mConnectionInFlight.getBluetoothDevice().getName()); + + mConnectionInFlight.getBluetoothDevice()); } } @@ -1150,6 +1176,7 @@ public class BluetoothDeviceConnectionPolicy { private synchronized void resetDeviceAvailableToConnect() { for (BluetoothDevicesInfo devInfo : mProfileToConnectableDevicesMap.values()) { devInfo.setDeviceAvailableToConnectLocked(true); + devInfo.resetDeviceIndex(); } } @@ -1168,12 +1195,13 @@ public class BluetoothDeviceConnectionPolicy { writer.print( "Num of Paired devices: " + devInfo.getNumberOfPairedDevicesLocked() + "\t"); writer.print("Active Connections: " + devInfo.getNumberOfActiveConnectionsLocked()); + writer.println("Num of paired devices: " + devInfo.getNumberOfPairedDevicesLocked()); writer.println(); List deviceInfoList = devInfo.getDeviceInfoList(); if (deviceInfoList != null) { for (BluetoothDevicesInfo.DeviceInfo devicesInfo : deviceInfoList) { if (devicesInfo.getBluetoothDevice() != null) { - writer.print(devicesInfo.getBluetoothDevice().getName() + ":"); + writer.print(devicesInfo.getBluetoothDevice() + ":"); writer.print(devicesInfo.getConnectionState() + "\t"); } } @@ -1212,6 +1240,9 @@ public class BluetoothDeviceConnectionPolicy { * @return true if the write was successful, false otherwise */ public synchronized boolean writeDeviceInfoToSettings(ConnectionParams params) { + if (!mAllowReadWriteToSettings) { + return false; + } boolean writeSuccess = true; Integer profileToUpdate = params.getBluetoothProfile(); @@ -1237,8 +1268,9 @@ public class BluetoothDeviceConnectionPolicy { // joinedDeviceNames has something like "22:22:33:44:55:AB,22:23:xx:xx:xx:xx" // mac addresses of connectable devices separated by a delimiter String joinedDeviceNames = sb.toString(); - Log.d(TAG, "Profile: " + profileToUpdate + " Writing: " + joinedDeviceNames); - + if (DBG) { + Log.d(TAG, "Profile: " + profileToUpdate + " Writing: " + joinedDeviceNames); + } long userId = ActivityManager.getCurrentUser(); switch (profileToUpdate) { case BluetoothProfile.A2DP_SINK: @@ -1297,6 +1329,9 @@ public class BluetoothDeviceConnectionPolicy { return false; } } + if(!mAllowReadWriteToSettings) { + return false; + } // Read from Settings.Secure for the current user. There are 3 keys 1 each for Phone // (HFP & PBAP), 1 for Music (A2DP) and 1 for Messaging device (MAP) long userId = ActivityManager.getCurrentUser(); diff --git a/service/src/com/android/car/BluetoothDevicesInfo.java b/service/src/com/android/car/BluetoothDevicesInfo.java index a383f0499c..a2d5192648 100644 --- a/service/src/com/android/car/BluetoothDevicesInfo.java +++ b/service/src/com/android/car/BluetoothDevicesInfo.java @@ -537,6 +537,10 @@ public class BluetoothDevicesInfo { return mConnectionInfo.mNumActiveConnections; } + public void resetDeviceIndex() { + mConnectionInfo.mDeviceIndex = 0; + } + /** * Reset the connection related bookkeeping information. * Called on a BluetoothAdapter Off to clean slate diff --git a/tests/carservice_unit_test/Android.mk b/tests/carservice_unit_test/Android.mk index 4c57c6e980..1ec200850a 100644 --- a/tests/carservice_unit_test/Android.mk +++ b/tests/carservice_unit_test/Android.mk @@ -34,6 +34,6 @@ LOCAL_PROGUARD_ENABLED := disabled LOCAL_INSTRUMENTATION_FOR := CarService LOCAL_JAVA_LIBRARIES := android.car android.test.runner -LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test +LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test android-support-test mockito-target-minus-junit4 include $(BUILD_PACKAGE) diff --git a/tests/carservice_unit_test/AndroidManifest.xml b/tests/carservice_unit_test/AndroidManifest.xml index 36b86e71e3..0f6727598a 100644 --- a/tests/carservice_unit_test/AndroidManifest.xml +++ b/tests/carservice_unit_test/AndroidManifest.xml @@ -18,7 +18,7 @@ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" package="com.android.car.carservice_unittest" android:sharedUserId="android.uid.system" > - diff --git a/tests/carservice_unit_test/src/com/android/car/BluetoothAutoConnectPolicyTest.java b/tests/carservice_unit_test/src/com/android/car/BluetoothAutoConnectPolicyTest.java new file mode 100644 index 0000000000..1bc1130f63 --- /dev/null +++ b/tests/carservice_unit_test/src/com/android/car/BluetoothAutoConnectPolicyTest.java @@ -0,0 +1,371 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.car; + +import android.bluetooth.BluetoothA2dpSink; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothHeadsetClient; +import android.bluetooth.BluetoothMapClient; +import android.bluetooth.BluetoothPbapClient; +import android.bluetooth.BluetoothProfile; +import android.car.ICarUserService; +import android.car.hardware.CarPropertyValue; +import android.car.hardware.cabin.CarCabinManager; +import android.car.hardware.property.CarPropertyEvent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Handler; +import android.os.Looper; +import android.os.RemoteException; +import android.test.AndroidTestCase; + +import static org.mockito.Mockito.*; + +import org.mockito.Matchers; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.junit.Test; + +import java.util.List; + +/** + * Unit tests for the {@link BluetoothDeviceConnectionPolicy}. + * Isolate and test the policy's functionality - test if it finds the right device(s) per profile to + * connect to when triggered by an appropriate event. + * + * The following services are mocked: + * 1. {@link CarBluetoothUserService} - connect requests to the Bluetooth stack are stubbed out + * and connection results can be injected (imitating results from the stack) + * 2. {@link CarCabinService} & {@link CarSensorService} - Fake vehicle events are injected to the + * policy's Broadcast Receiver. + */ +public class BluetoothAutoConnectPolicyTest extends AndroidTestCase { + private static final String TAG = "BTPolicyTest"; + private BluetoothDeviceConnectionPolicy mBluetoothDeviceConnectionPolicyTest; + private BluetoothAdapter mBluetoothAdapter; + private BroadcastReceiver mReceiver; + private BluetoothDeviceConnectionPolicy.CarPropertyListener mCabinEventListener; + private Handler mMainHandler; + private Context mockContext; + // Mock of Services that the policy interacts with + private CarCabinService mockCarCabinService; + private CarSensorService mockCarSensorService; + private CarBluetoothUserService mockBluetoothUserService; + private PerUserCarServiceHelper mockPerUserCarServiceHelper; + private ICarUserService mockPerUserCarService; + // Timeouts + private static final int CONNECTION_STATE_CHANGE_TIME = 500; //ms + private static final int CONNECTION_REQUEST_TIMEOUT = 10000;//ms + private static final int WAIT_FOR_COMPLETION_TIME = 1000;//ms + + @Override + protected void setUp() throws Exception { + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + mMainHandler = new Handler(Looper.getMainLooper()); + makeMockServices(); + super.setUp(); + } + + @Override + protected void tearDown() throws Exception { + mBluetoothDeviceConnectionPolicyTest.release(); + super.tearDown(); + } + /****************************************** Utility methods **********************************/ + + /** + * Pair a device on the given profile. Note that this is not real Bluetooth Pairing. This is + * just adding a (fake) BluetoothDevice to the policy's records, which is what a real Bluetooth + * pairing would have done. + * + * @param device - Bluetooth device + * @param profile - Profile to pair on. + */ + private void pairDeviceOnProfile(BluetoothDevice device, Integer profile) { + sendFakeConnectionStateChangeOnProfile(device, profile, true); + } + + /** + * Inject a fake connection state changed intent to the policy's Broadcast Receiver + * + * @param device - Bluetooth Device + * @param profile - Bluetooth Profile + * @param connect - connection Success or Failure + */ + private void sendFakeConnectionStateChangeOnProfile(BluetoothDevice device, Integer profile, + boolean connect) { + assertNotNull(mReceiver); + Intent connectionIntent = createBluetoothConnectionStateChangedIntent(profile, device, + connect); + mReceiver.onReceive(null, connectionIntent); + } + + /** + * Utility function to create a Connection State Changed Intent for the given profile and device + * + * @param profile - Bluetooth profile + * @param device - Bluetooth Device + * @param connect - Connection Success or Failure + * @return - Connection State Changed Intent with the filled up EXTRAs + */ + private Intent createBluetoothConnectionStateChangedIntent(int profile, BluetoothDevice device, + boolean connect) { + Intent connectionIntent; + switch (profile) { + case BluetoothProfile.A2DP_SINK: + connectionIntent = new Intent(BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED); + break; + case BluetoothProfile.HEADSET_CLIENT: + connectionIntent = new Intent( + BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED); + break; + case BluetoothProfile.MAP_CLIENT: + connectionIntent = new Intent(BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED); + break; + case BluetoothProfile.PBAP_CLIENT: + connectionIntent = new Intent(BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED); + break; + default: + return null; + } + connectionIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); + if (connect) { + connectionIntent.putExtra(BluetoothProfile.EXTRA_STATE, + BluetoothProfile.STATE_CONNECTED); + } else { + connectionIntent.putExtra(BluetoothProfile.EXTRA_STATE, + BluetoothProfile.STATE_DISCONNECTED); + } + return connectionIntent; + } + + /** + * Trigger a fake vehicle Event by injecting directly into the policy's Event Listener. + * Note that a Cabin Event (Door unlock) is used here. The default policy has a Cabin Event + * listener. + * The event can be changed to what is appropriate as long as there is a corresponding listener + * implemented in the policy + */ + private void triggerFakeVehicleEvent() throws RemoteException { + assertNotNull(mCabinEventListener); + CarPropertyValue value = new CarPropertyValue<>(CarCabinManager.ID_DOOR_LOCK, + false); + CarPropertyEvent event = new CarPropertyEvent( + CarPropertyEvent.PROPERTY_EVENT_PROPERTY_CHANGE, value); + mCabinEventListener.onEvent(event); + } + + /** + * Put all the mock creations in one place. To be called from setup() + */ + private void makeMockServices() { + mockContext = mock(Context.class); + mockCarCabinService = mock(CarCabinService.class); + mockCarSensorService = mock(CarSensorService.class); + mockPerUserCarServiceHelper = mock(PerUserCarServiceHelper.class); + mockPerUserCarService = mock(ICarUserService.class); + mockBluetoothUserService = mock(CarBluetoothUserService.class, + Mockito.withSettings().verboseLogging()); + } + + /** + * Set up the common mock behavior to be used in all the tests. + * Mainly mocks the Bluetooth Stack behavior + * + * @param connectionResult - result to return when a connection is requested. + */ + private void setupBluetoothMockBehavior(final boolean connectionResult) throws Exception { + // Return the mock Bluetooth User Service when asked for + when(mockPerUserCarService.getBluetoothUserService()).thenReturn(mockBluetoothUserService); + when(mockBluetoothUserService.isBluetoothConnectionProxyAvailable( + Matchers.anyInt())).thenReturn(true); + + // When the policy issues a connect request, mimic a connection state changed intent + // broadcast on the policy's main thread. The connect request comes in from the + // BluetoothAutoConnectStateMachine's thread. + Mockito.doAnswer(new Answer() { + @Override + public Void answer(InvocationOnMock invocationOnMock) throws Throwable { + if (invocationOnMock.getArguments().length < 2) { + return null; + } + final int profile = (int) invocationOnMock.getArguments()[0]; + final BluetoothDevice device = (BluetoothDevice) invocationOnMock.getArguments()[1]; + // BroadcastReceivers run on the main thread. Post a Bluetooth Profile Connection + // State Change intent on the main thread imitating what the receiver would have + // received from the Bluetooth stack + mMainHandler.postDelayed(new Runnable() { + @Override + public void run() { + mReceiver.onReceive(null, + createBluetoothConnectionStateChangedIntent(profile, device, + connectionResult)); + } + }, CONNECTION_STATE_CHANGE_TIME); + return null; + } + }).when(mockBluetoothUserService).bluetoothConnectToProfile(anyInt(), + any(BluetoothDevice.class)); + } + + /** + * Utility method called from the beginning of every test to create and init the policy + */ + private void createAndSetupBluetoothPolicy() { + mBluetoothDeviceConnectionPolicyTest = BluetoothDeviceConnectionPolicy.create(mockContext, + mockCarCabinService, mockCarSensorService, mockPerUserCarServiceHelper); + mBluetoothDeviceConnectionPolicyTest.setAllowReadWriteToSettings(false); + mBluetoothDeviceConnectionPolicyTest.init(); + + mReceiver = mBluetoothDeviceConnectionPolicyTest.getBluetoothBroadcastReceiver(); + assertNotNull(mReceiver); + BluetoothDeviceConnectionPolicy.UserServiceConnectionCallback serviceConnectionCallback = + mBluetoothDeviceConnectionPolicyTest.getServiceCallback(); + assertNotNull(serviceConnectionCallback); + mCabinEventListener = mBluetoothDeviceConnectionPolicyTest.getCarPropertyListener(); + assertNotNull(mCabinEventListener); + + serviceConnectionCallback.onServiceConnected(mockPerUserCarService); + } + + /** + * Utility method called from the end of every test to cleanup and release the policy + */ + private Intent createBluetoothBondStateChangedIntent(BluetoothDevice device, boolean bonded) { + // Unbond the device + Intent bondStateIntent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED); + if (!bonded) { + bondStateIntent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE); + } else { + bondStateIntent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_BONDED); + } + bondStateIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); + return bondStateIntent; + } + + /************************************** Test Methods *****************************************/ + /** + * Basic test - + * 1. Pair one device to the car on all profiles. + * 2. Disconnect the device + * 3. Inject a fake vehicle event + * 4. Verify that we get connection requests on all the profiles with that paired device + */ + @Test + public void testAutoConnectOneDevice() throws Exception { + setupBluetoothMockBehavior(true); // For this test always return Connection Success + createAndSetupBluetoothPolicy(); + // Tell the policy a new device connected - this mimics pairing + BluetoothDevice device1 = mBluetoothAdapter.getRemoteDevice("DE:AD:BE:EF:00:01"); + // Pair (and Connect) device1 on all the Bluetooth profiles. + List profilesToConnect = + mBluetoothDeviceConnectionPolicyTest.getProfilesToConnect(); + for (Integer profile : profilesToConnect) { + pairDeviceOnProfile(device1, profile); + } + + // Disconnect so we can test Autoconnect by sending a vehicle event + for (Integer profile : profilesToConnect) { + sendFakeConnectionStateChangeOnProfile(device1, profile, false); + } + // At this point DEADBEEF0001 is paired but disconnected to the vehicle + // Now, trigger a connection and check if we connected to DEADBEEF0001 on all profiles + triggerFakeVehicleEvent(); + // Verify that on all profiles, device1 connected + for (Integer profile : mBluetoothDeviceConnectionPolicyTest.getProfilesToConnect()) { + verify(mockBluetoothUserService, + Mockito.timeout(CONNECTION_REQUEST_TIMEOUT).times(1)).bluetoothConnectToProfile( + profile, device1); + } + + // Before we cleanup wait for the last Connection Status change from + // setupBluetoothMockBehavior + // is broadcast to the policy. + Thread.sleep(WAIT_FOR_COMPLETION_TIME); + // Inject an Unbond event to the policy + mReceiver.onReceive(null, createBluetoothBondStateChangedIntent(device1, false)); + } + + /** + * Multi device test + * 1. Pair 4 different devices 2 on HFP and PBAP (since they allow 2 connections) and 1 each on + * A2DP and MAP + * 2. Disconnect all devices + * 3. Inject a fake vehicle event. + * 4. Verify that the right devices connect on the right profiles ( the snapshot recreated) + */ + @Test + public void testAutoConnectMultiDevice() throws Exception { + setupBluetoothMockBehavior(true); // For this test always return Connection Success + createAndSetupBluetoothPolicy(); + BluetoothDevice device1 = mBluetoothAdapter.getRemoteDevice("DE:AD:BE:EF:00:01"); + BluetoothDevice device2 = mBluetoothAdapter.getRemoteDevice("DE:AD:BE:EF:00:02"); + BluetoothDevice device3 = mBluetoothAdapter.getRemoteDevice("DE:AD:BE:EF:00:03"); + BluetoothDevice device4 = mBluetoothAdapter.getRemoteDevice("DE:AD:BE:EF:00:04"); + + // Pair 4 different devices on the 4 profiles. HFP and PBAP are connected on the same + // device(s) + pairDeviceOnProfile(device1, BluetoothProfile.HEADSET_CLIENT); + pairDeviceOnProfile(device1, BluetoothProfile.PBAP_CLIENT); + pairDeviceOnProfile(device2, BluetoothProfile.HEADSET_CLIENT); + pairDeviceOnProfile(device2, BluetoothProfile.PBAP_CLIENT); + pairDeviceOnProfile(device3, BluetoothProfile.A2DP_SINK); + pairDeviceOnProfile(device4, BluetoothProfile.MAP_CLIENT); + + // Disconnect all the 4 devices on the respective connected profiles + sendFakeConnectionStateChangeOnProfile(device1, BluetoothProfile.HEADSET_CLIENT, false); + sendFakeConnectionStateChangeOnProfile(device1, BluetoothProfile.PBAP_CLIENT, false); + sendFakeConnectionStateChangeOnProfile(device2, BluetoothProfile.HEADSET_CLIENT, false); + sendFakeConnectionStateChangeOnProfile(device2, BluetoothProfile.PBAP_CLIENT, false); + sendFakeConnectionStateChangeOnProfile(device3, BluetoothProfile.A2DP_SINK, false); + sendFakeConnectionStateChangeOnProfile(device4, BluetoothProfile.MAP_CLIENT, false); + + triggerFakeVehicleEvent(); + + verify(mockBluetoothUserService, + Mockito.timeout(CONNECTION_REQUEST_TIMEOUT).times(1)).bluetoothConnectToProfile( + BluetoothProfile.HEADSET_CLIENT, device1); + + verify(mockBluetoothUserService, + Mockito.timeout(CONNECTION_REQUEST_TIMEOUT).times(1)).bluetoothConnectToProfile( + BluetoothProfile.PBAP_CLIENT, device1); + verify(mockBluetoothUserService, + Mockito.timeout(CONNECTION_REQUEST_TIMEOUT).times(1)).bluetoothConnectToProfile( + BluetoothProfile.HEADSET_CLIENT, device2); + verify(mockBluetoothUserService, + Mockito.timeout(CONNECTION_REQUEST_TIMEOUT).times(1)).bluetoothConnectToProfile( + BluetoothProfile.PBAP_CLIENT, device2); + verify(mockBluetoothUserService, + Mockito.timeout(CONNECTION_REQUEST_TIMEOUT).times(1)).bluetoothConnectToProfile( + BluetoothProfile.A2DP_SINK, device3); + verify(mockBluetoothUserService, + Mockito.timeout(CONNECTION_REQUEST_TIMEOUT).times(1)).bluetoothConnectToProfile( + BluetoothProfile.MAP_CLIENT, device4); + + // Before we cleanup wait for the last Connection Status change from + // setupBluetoothMockBehavior is broadcast to the policy. + Thread.sleep(WAIT_FOR_COMPLETION_TIME); + // Inject an Unbond event to the policy + mReceiver.onReceive(null, createBluetoothBondStateChangedIntent(device1, false)); + mReceiver.onReceive(null, createBluetoothBondStateChangedIntent(device2, false)); + mReceiver.onReceive(null, createBluetoothBondStateChangedIntent(device3, false)); + mReceiver.onReceive(null, createBluetoothBondStateChangedIntent(device4, false)); + } +} \ No newline at end of file -- cgit v1.2.3 From 3ae759551710424c01c2e985bfc13e7e3d4ee1cb Mon Sep 17 00:00:00 2001 From: Pavel Maltsev Date: Tue, 25 Jul 2017 14:57:08 -0700 Subject: Fix activity monitoring test Test: runtest -x packages/services/Car/tests/carservice_test/src/com/android/car/test/SystemActivityMonitoringServiceTest.java Change-Id: Id6ca97f14f9b46186b4d1f2d3e34849207615d05 Fix: b/62224020 --- .../test/SystemActivityMonitoringServiceTest.java | 5 +++++ .../car/vehiclehal/test/MockedVehicleHal.java | 23 ++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/tests/carservice_test/src/com/android/car/test/SystemActivityMonitoringServiceTest.java b/tests/carservice_test/src/com/android/car/test/SystemActivityMonitoringServiceTest.java index 0b1e7189eb..3345605e9e 100644 --- a/tests/carservice_test/src/com/android/car/test/SystemActivityMonitoringServiceTest.java +++ b/tests/carservice_test/src/com/android/car/test/SystemActivityMonitoringServiceTest.java @@ -54,6 +54,11 @@ public class SystemActivityMonitoringServiceTest extends MockedCarTestBase { // blocking activity. mDrivingStatusHandler.setDrivingStatusRestricted(drivingStatusRestricted); + // Due to asynchronous nature of Car Service initialization, if we won't wait we may inject + // an event while SensorHalService is not subscribed yet. + assertTrue(getMockedVehicleHal() + .waitForSubscriber(VehicleProperty.DRIVING_STATUS, TIMEOUT_MS)); + VehiclePropValue injectValue = VehiclePropValueBuilder.newBuilder(VehicleProperty.DRIVING_STATUS) .setTimestamp(SystemClock.elapsedRealtimeNanos()) diff --git a/vehicle-hal-support-lib/src/com/android/car/vehiclehal/test/MockedVehicleHal.java b/vehicle-hal-support-lib/src/com/android/car/vehiclehal/test/MockedVehicleHal.java index 1a5b8c6dcc..0da3565fdf 100644 --- a/vehicle-hal-support-lib/src/com/android/car/vehiclehal/test/MockedVehicleHal.java +++ b/vehicle-hal-support-lib/src/com/android/car/vehiclehal/test/MockedVehicleHal.java @@ -21,8 +21,6 @@ import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.fail; -import com.google.android.collect.Lists; - import android.hardware.automotive.vehicle.V2_0.IVehicle; import android.hardware.automotive.vehicle.V2_0.IVehicleCallback; import android.hardware.automotive.vehicle.V2_0.StatusCode; @@ -31,6 +29,9 @@ import android.hardware.automotive.vehicle.V2_0.VehiclePropConfig; import android.hardware.automotive.vehicle.V2_0.VehiclePropValue; import android.hardware.automotive.vehicle.V2_0.VehiclePropertyAccess; import android.os.RemoteException; +import android.os.SystemClock; + +import com.google.android.collect.Lists; import java.util.ArrayList; import java.util.HashMap; @@ -74,6 +75,23 @@ public class MockedVehicleHal extends IVehicle.Stub { addProperty(config, new StaticPropertyHandler(value)); } + public boolean waitForSubscriber(int propId, long timeoutMillis) { + long startTime = SystemClock.elapsedRealtime(); + try { + synchronized (this) { + while (mSubscribers.get(propId) == null) { + long waitMillis = startTime - SystemClock.elapsedRealtime() + timeoutMillis; + if (waitMillis < 0) break; + wait(waitMillis); + } + + return mSubscribers.get(propId) != null; + } + } catch (InterruptedException e) { + return false; + } + } + public synchronized void injectEvent(VehiclePropValue value) { List callbacks = mSubscribers.get(value.prop); assertNotNull("Injecting event failed for property: " + value.prop @@ -156,6 +174,7 @@ public class MockedVehicleHal extends IVehicle.Stub { if (subscribers == null) { subscribers = new ArrayList<>(); mSubscribers.put(opt.propId, subscribers); + notifyAll(); } subscribers.add(callback); } -- cgit v1.2.3 From 4fa22779c643b3daa07a3f1e356eb345999b5607 Mon Sep 17 00:00:00 2001 From: Gaurav Sarode Date: Tue, 25 Jul 2017 15:13:34 -0700 Subject: cluster-logging: Disable build in PDK bug: 63965780 Test: local build Change-Id: I5de9b39f1d806f2a7cb501f67721c6a1f238ad59 --- car-cluster-logging-renderer/Android.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/car-cluster-logging-renderer/Android.mk b/car-cluster-logging-renderer/Android.mk index 8fb76748c9..dd1d0cab4e 100644 --- a/car-cluster-logging-renderer/Android.mk +++ b/car-cluster-logging-renderer/Android.mk @@ -13,7 +13,7 @@ # limitations under the License. # # - +ifneq ($(TARGET_BUILD_PDK),true) LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) @@ -32,3 +32,4 @@ LOCAL_PROGUARD_ENABLED := disabled LOCAL_JAVA_LIBRARIES += android.car include $(BUILD_PACKAGE) +endif -- cgit v1.2.3 From be4780ccce616f1ae9311eaf6967195360cb1e33 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Wed, 2 Aug 2017 10:20:36 -0700 Subject: Car: remove use of -static hidl java These libraries are being removed. Now, the regular java library can be used as both a static and non-static library, we are removing these duplicate libraries which cause several types problems (such as undefined behavior when both the static and non-static libs are loaded). Bug: 36376126 Test: no build/runtime errors running test Change-Id: I7efb5d12d080c4c2006264b6fc119cf4292a5494 --- service/Android.mk | 8 ++++---- tests/EmbeddedKitchenSinkApp/Android.mk | 2 +- tests/android_car_api_test/Android.mk | 2 +- tests/vehiclehal_test/Android.mk | 4 ++-- vehicle-hal-support-lib/Android.mk | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/service/Android.mk b/service/Android.mk index 46bb9da1b5..0192823e2d 100644 --- a/service/Android.mk +++ b/service/Android.mk @@ -38,8 +38,8 @@ LOCAL_PROGUARD_ENABLED := disabled LOCAL_JAVA_LIBRARIES += android.car LOCAL_STATIC_JAVA_LIBRARIES += \ - android.hardware.automotive.vehicle-V2.0-java-static \ - android.hardware.automotive.vehicle-V2.1-java-static \ + android.hardware.automotive.vehicle-V2.0-java \ + android.hardware.automotive.vehicle-V2.1-java \ vehicle-hal-support-lib \ car-systemtest \ @@ -57,8 +57,8 @@ LOCAL_MODULE := car-service-lib-for-test LOCAL_JAVA_LIBRARIES += android.car LOCAL_STATIC_JAVA_LIBRARIES += \ - android.hardware.automotive.vehicle-V2.0-java-static \ - android.hardware.automotive.vehicle-V2.1-java-static \ + android.hardware.automotive.vehicle-V2.0-java \ + android.hardware.automotive.vehicle-V2.1-java \ vehicle-hal-support-lib \ car-systemtest \ diff --git a/tests/EmbeddedKitchenSinkApp/Android.mk b/tests/EmbeddedKitchenSinkApp/Android.mk index d6619022ed..c8ece9f0c0 100644 --- a/tests/EmbeddedKitchenSinkApp/Android.mk +++ b/tests/EmbeddedKitchenSinkApp/Android.mk @@ -40,7 +40,7 @@ LOCAL_PROGUARD_ENABLED := disabled LOCAL_DEX_PREOPT := false LOCAL_STATIC_JAVA_LIBRARIES += \ - android.hardware.automotive.vehicle-V2.0-java-static \ + android.hardware.automotive.vehicle-V2.0-java \ vehicle-hal-support-lib \ car-service-lib-for-test \ diff --git a/tests/android_car_api_test/Android.mk b/tests/android_car_api_test/Android.mk index 306a240f51..0e47bb652d 100644 --- a/tests/android_car_api_test/Android.mk +++ b/tests/android_car_api_test/Android.mk @@ -35,7 +35,7 @@ LOCAL_PROGUARD_ENABLED := disabled LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test LOCAL_STATIC_JAVA_LIBRARIES += \ android-support-test \ - android.hardware.automotive.vehicle-V2.0-java-static \ + android.hardware.automotive.vehicle-V2.0-java \ LOCAL_JAVA_LIBRARIES := android.car android.test.runner diff --git a/tests/vehiclehal_test/Android.mk b/tests/vehiclehal_test/Android.mk index 43aa41f484..2c85c653c3 100644 --- a/tests/vehiclehal_test/Android.mk +++ b/tests/vehiclehal_test/Android.mk @@ -33,8 +33,8 @@ LOCAL_PROGUARD_ENABLED := disabled LOCAL_STATIC_JAVA_LIBRARIES += vehicle-hal-support-lib \ android-support-test \ - android.hardware.automotive.vehicle-V2.0-java-static \ - android.hardware.automotive.vehicle-V2.1-java-static + android.hardware.automotive.vehicle-V2.0-java \ + android.hardware.automotive.vehicle-V2.1-java LOCAL_JAVA_LIBRARIES := android.car android.test.runner diff --git a/vehicle-hal-support-lib/Android.mk b/vehicle-hal-support-lib/Android.mk index 638e5cf26e..688fb24778 100644 --- a/vehicle-hal-support-lib/Android.mk +++ b/vehicle-hal-support-lib/Android.mk @@ -24,8 +24,8 @@ LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_STATIC_JAVA_LIBRARIES := \ - android.hardware.automotive.vehicle-V2.0-java-static \ - android.hardware.automotive.vehicle-V2.1-java-static \ + android.hardware.automotive.vehicle-V2.0-java \ + android.hardware.automotive.vehicle-V2.1-java \ junit \ legacy-android-test -- cgit v1.2.3 From a8cc03920111dd3150f313269125849b01b01058 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Wed, 2 Aug 2017 20:40:23 +0000 Subject: Revert "Car: remove use of -static hidl java" This reverts commit be4780ccce616f1ae9311eaf6967195360cb1e33. Reason for revert: missing IBase dependency Change-Id: I9146352c7aea1a5287d54f0fdc054a27db64bb40 --- service/Android.mk | 8 ++++---- tests/EmbeddedKitchenSinkApp/Android.mk | 2 +- tests/android_car_api_test/Android.mk | 2 +- tests/vehiclehal_test/Android.mk | 4 ++-- vehicle-hal-support-lib/Android.mk | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/service/Android.mk b/service/Android.mk index 0192823e2d..46bb9da1b5 100644 --- a/service/Android.mk +++ b/service/Android.mk @@ -38,8 +38,8 @@ LOCAL_PROGUARD_ENABLED := disabled LOCAL_JAVA_LIBRARIES += android.car LOCAL_STATIC_JAVA_LIBRARIES += \ - android.hardware.automotive.vehicle-V2.0-java \ - android.hardware.automotive.vehicle-V2.1-java \ + android.hardware.automotive.vehicle-V2.0-java-static \ + android.hardware.automotive.vehicle-V2.1-java-static \ vehicle-hal-support-lib \ car-systemtest \ @@ -57,8 +57,8 @@ LOCAL_MODULE := car-service-lib-for-test LOCAL_JAVA_LIBRARIES += android.car LOCAL_STATIC_JAVA_LIBRARIES += \ - android.hardware.automotive.vehicle-V2.0-java \ - android.hardware.automotive.vehicle-V2.1-java \ + android.hardware.automotive.vehicle-V2.0-java-static \ + android.hardware.automotive.vehicle-V2.1-java-static \ vehicle-hal-support-lib \ car-systemtest \ diff --git a/tests/EmbeddedKitchenSinkApp/Android.mk b/tests/EmbeddedKitchenSinkApp/Android.mk index c8ece9f0c0..d6619022ed 100644 --- a/tests/EmbeddedKitchenSinkApp/Android.mk +++ b/tests/EmbeddedKitchenSinkApp/Android.mk @@ -40,7 +40,7 @@ LOCAL_PROGUARD_ENABLED := disabled LOCAL_DEX_PREOPT := false LOCAL_STATIC_JAVA_LIBRARIES += \ - android.hardware.automotive.vehicle-V2.0-java \ + android.hardware.automotive.vehicle-V2.0-java-static \ vehicle-hal-support-lib \ car-service-lib-for-test \ diff --git a/tests/android_car_api_test/Android.mk b/tests/android_car_api_test/Android.mk index 0e47bb652d..306a240f51 100644 --- a/tests/android_car_api_test/Android.mk +++ b/tests/android_car_api_test/Android.mk @@ -35,7 +35,7 @@ LOCAL_PROGUARD_ENABLED := disabled LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test LOCAL_STATIC_JAVA_LIBRARIES += \ android-support-test \ - android.hardware.automotive.vehicle-V2.0-java \ + android.hardware.automotive.vehicle-V2.0-java-static \ LOCAL_JAVA_LIBRARIES := android.car android.test.runner diff --git a/tests/vehiclehal_test/Android.mk b/tests/vehiclehal_test/Android.mk index 2c85c653c3..43aa41f484 100644 --- a/tests/vehiclehal_test/Android.mk +++ b/tests/vehiclehal_test/Android.mk @@ -33,8 +33,8 @@ LOCAL_PROGUARD_ENABLED := disabled LOCAL_STATIC_JAVA_LIBRARIES += vehicle-hal-support-lib \ android-support-test \ - android.hardware.automotive.vehicle-V2.0-java \ - android.hardware.automotive.vehicle-V2.1-java + android.hardware.automotive.vehicle-V2.0-java-static \ + android.hardware.automotive.vehicle-V2.1-java-static LOCAL_JAVA_LIBRARIES := android.car android.test.runner diff --git a/vehicle-hal-support-lib/Android.mk b/vehicle-hal-support-lib/Android.mk index 688fb24778..638e5cf26e 100644 --- a/vehicle-hal-support-lib/Android.mk +++ b/vehicle-hal-support-lib/Android.mk @@ -24,8 +24,8 @@ LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_STATIC_JAVA_LIBRARIES := \ - android.hardware.automotive.vehicle-V2.0-java \ - android.hardware.automotive.vehicle-V2.1-java \ + android.hardware.automotive.vehicle-V2.0-java-static \ + android.hardware.automotive.vehicle-V2.1-java-static \ junit \ legacy-android-test -- cgit v1.2.3 From 14f54c5d63c72ae99542cdfc13e8a6271f4780a2 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Wed, 2 Aug 2017 20:41:36 +0000 Subject: Reland "Car: remove use of -static hidl java" This reverts commit a8cc03920111dd3150f313269125849b01b01058. Note, need to add base dependencies because they aren't available by default in all branches and the "java-static" libraries originally included them. Test: no link errors Bug: 36376126 Change-Id: I9423a53524e5b3d5f54d8ec7376774f6ab21eb0e --- service/Android.mk | 10 ++++++---- tests/EmbeddedKitchenSinkApp/Android.mk | 3 ++- tests/android_car_api_test/Android.mk | 3 ++- tests/vehiclehal_test/Android.mk | 5 +++-- vehicle-hal-support-lib/Android.mk | 5 +++-- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/service/Android.mk b/service/Android.mk index 46bb9da1b5..9bd5e124a5 100644 --- a/service/Android.mk +++ b/service/Android.mk @@ -38,8 +38,9 @@ LOCAL_PROGUARD_ENABLED := disabled LOCAL_JAVA_LIBRARIES += android.car LOCAL_STATIC_JAVA_LIBRARIES += \ - android.hardware.automotive.vehicle-V2.0-java-static \ - android.hardware.automotive.vehicle-V2.1-java-static \ + android.hidl.base-V1.0-java \ + android.hardware.automotive.vehicle-V2.0-java \ + android.hardware.automotive.vehicle-V2.1-java \ vehicle-hal-support-lib \ car-systemtest \ @@ -57,8 +58,9 @@ LOCAL_MODULE := car-service-lib-for-test LOCAL_JAVA_LIBRARIES += android.car LOCAL_STATIC_JAVA_LIBRARIES += \ - android.hardware.automotive.vehicle-V2.0-java-static \ - android.hardware.automotive.vehicle-V2.1-java-static \ + android.hidl.base-V1.0-java \ + android.hardware.automotive.vehicle-V2.0-java \ + android.hardware.automotive.vehicle-V2.1-java \ vehicle-hal-support-lib \ car-systemtest \ diff --git a/tests/EmbeddedKitchenSinkApp/Android.mk b/tests/EmbeddedKitchenSinkApp/Android.mk index d6619022ed..37c79f75a3 100644 --- a/tests/EmbeddedKitchenSinkApp/Android.mk +++ b/tests/EmbeddedKitchenSinkApp/Android.mk @@ -40,7 +40,8 @@ LOCAL_PROGUARD_ENABLED := disabled LOCAL_DEX_PREOPT := false LOCAL_STATIC_JAVA_LIBRARIES += \ - android.hardware.automotive.vehicle-V2.0-java-static \ + android.hidl.base-V1.0-java \ + android.hardware.automotive.vehicle-V2.0-java \ vehicle-hal-support-lib \ car-service-lib-for-test \ diff --git a/tests/android_car_api_test/Android.mk b/tests/android_car_api_test/Android.mk index 306a240f51..58a12885c8 100644 --- a/tests/android_car_api_test/Android.mk +++ b/tests/android_car_api_test/Android.mk @@ -35,7 +35,8 @@ LOCAL_PROGUARD_ENABLED := disabled LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test LOCAL_STATIC_JAVA_LIBRARIES += \ android-support-test \ - android.hardware.automotive.vehicle-V2.0-java-static \ + android.hidl.base-V1.0-java \ + android.hardware.automotive.vehicle-V2.0-java \ LOCAL_JAVA_LIBRARIES := android.car android.test.runner diff --git a/tests/vehiclehal_test/Android.mk b/tests/vehiclehal_test/Android.mk index 43aa41f484..a22ee1b301 100644 --- a/tests/vehiclehal_test/Android.mk +++ b/tests/vehiclehal_test/Android.mk @@ -33,8 +33,9 @@ LOCAL_PROGUARD_ENABLED := disabled LOCAL_STATIC_JAVA_LIBRARIES += vehicle-hal-support-lib \ android-support-test \ - android.hardware.automotive.vehicle-V2.0-java-static \ - android.hardware.automotive.vehicle-V2.1-java-static + android.hidl.base-V1.0-java \ + android.hardware.automotive.vehicle-V2.0-java \ + android.hardware.automotive.vehicle-V2.1-java LOCAL_JAVA_LIBRARIES := android.car android.test.runner diff --git a/vehicle-hal-support-lib/Android.mk b/vehicle-hal-support-lib/Android.mk index 638e5cf26e..9ff39c60b8 100644 --- a/vehicle-hal-support-lib/Android.mk +++ b/vehicle-hal-support-lib/Android.mk @@ -24,8 +24,9 @@ LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_STATIC_JAVA_LIBRARIES := \ - android.hardware.automotive.vehicle-V2.0-java-static \ - android.hardware.automotive.vehicle-V2.1-java-static \ + android.hidl.base-V1.0-java \ + android.hardware.automotive.vehicle-V2.0-java \ + android.hardware.automotive.vehicle-V2.1-java \ junit \ legacy-android-test -- cgit v1.2.3 From 50fe95ef595240463597cfd15b582fec59f043a4 Mon Sep 17 00:00:00 2001 From: Scott Randolph Date: Thu, 3 Aug 2017 15:09:41 -0700 Subject: Honor audio focus in kitchen system test cases Nav sounds from the test panel were not asking for focus. Now they are. Test: Run on Mojave Bug: 38389934 Change-Id: I6c2a921d1784ea07b614ad98391781503fc9eddc --- .../src/com/google/android/car/kitchensink/audio/AudioPlayer.java | 3 ++- .../com/google/android/car/kitchensink/audio/AudioTestFragment.java | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/audio/AudioPlayer.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/audio/AudioPlayer.java index 618367dccf..74345aa823 100644 --- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/audio/AudioPlayer.java +++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/audio/AudioPlayer.java @@ -61,7 +61,8 @@ public class AudioPlayer { } } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) { if (isPlaying()) { - mPlayer.setVolume(0.5f, 0.5f); + // Duck to 20% volume (which matches system ducking as of this date) + mPlayer.setVolume(0.2f, 0.2f); } } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT && mRepeat) { if (isPlaying()) { diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/audio/AudioTestFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/audio/AudioTestFragment.java index dec0dc6397..81e8737c4f 100644 --- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/audio/AudioTestFragment.java +++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/audio/AudioTestFragment.java @@ -219,7 +219,9 @@ public class AudioTestFragment extends Fragment { mMediaPlay.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - mMusicPlayer.start(false, true, AudioManager.AUDIOFOCUS_GAIN); + boolean requestFocus = true; + boolean repeat = true; + mMusicPlayer.start(requestFocus, repeat, AudioManager.AUDIOFOCUS_GAIN); } }); mMediaPlayOnce = (Button) view.findViewById(R.id.button_media_play_once); -- cgit v1.2.3 From a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4c Mon Sep 17 00:00:00 2001 From: Steve Paik Date: Tue, 18 Jul 2017 15:51:26 -0700 Subject: Add getConfigForSensor to CarSensorManager Bug: 62876582 Test: Embedded Kitchen Sink works with VHAL emulator Change-Id: Ice937cbb8c207cae0cab7e5417c1a4c93e00171b --- .../src/android/car/hardware/CarSensorConfig.aidl | 19 +++ .../src/android/car/hardware/CarSensorConfig.java | 125 +++++++++++++++++++ .../src/android/car/hardware/CarSensorManager.java | 25 ++++ car-lib/src/android/car/hardware/ICarSensor.aidl | 6 + .../support/car/hardware/CarSensorConfig.java | 98 +++++++++++++++ .../support/car/hardware/CarSensorManager.java | 11 ++ .../car/hardware/CarSensorManagerEmbedded.java | 17 +++ service/src/com/android/car/CarSensorService.java | 17 +++ .../src/com/android/car/hal/SensorHalService.java | 137 ++++++++++++++------- .../EmbeddedKitchenSinkApp/res/values/strings.xml | 1 + .../kitchensink/sensor/SensorsTestFragment.java | 14 +++ 11 files changed, 428 insertions(+), 42 deletions(-) create mode 100644 car-lib/src/android/car/hardware/CarSensorConfig.aidl create mode 100644 car-lib/src/android/car/hardware/CarSensorConfig.java create mode 100644 car-support-lib/src/android/support/car/hardware/CarSensorConfig.java diff --git a/car-lib/src/android/car/hardware/CarSensorConfig.aidl b/car-lib/src/android/car/hardware/CarSensorConfig.aidl new file mode 100644 index 0000000000..480f751c54 --- /dev/null +++ b/car-lib/src/android/car/hardware/CarSensorConfig.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.car.hardware; + +parcelable CarSensorConfig; diff --git a/car-lib/src/android/car/hardware/CarSensorConfig.java b/car-lib/src/android/car/hardware/CarSensorConfig.java new file mode 100644 index 0000000000..8ba456b0cf --- /dev/null +++ b/car-lib/src/android/car/hardware/CarSensorConfig.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.car.hardware; + +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; +import java.util.ArrayList; + +/** + * A CarSensorConfig object corresponds to a single sensor type coming from the car. + * @hide + */ +public class CarSensorConfig implements Parcelable { + /** List of property specific mapped elements in bundle for WHEEL_TICK_DISTANCE sensor*/ + /** @hide */ + public final static String WHEEL_TICK_DISTANCE_SUPPORTED_WHEELS = + "android.car.wheelTickDistanceSupportedWhheels"; + /** @hide */ + public final static String WHEEL_TICK_DISTANCE_FRONT_LEFT_UM_PER_TICK = + "android.car.wheelTickDistanceFrontLeftUmPerTick"; + /** @hide */ + public final static String WHEEL_TICK_DISTANCE_FRONT_RIGHT_UM_PER_TICK = + "android.car.wheelTickDistanceFrontRightUmPerTick"; + /** @hide */ + public final static String WHEEL_TICK_DISTANCE_REAR_RIGHT_UM_PER_TICK = + "android.car.wheelTickDistanceRearRightUmPerTick"; + /** @hide */ + public final static String WHEEL_TICK_DISTANCE_REAR_LEFT_UM_PER_TICK = + "android.car.wheelTickDistanceRearLeftUmPerTick"; + + /** Config data stored in Bundle */ + private final Bundle mConfig; + private final int mType; + + /** @hide */ + public CarSensorConfig(Parcel in) { + mType = in.readInt(); + mConfig = in.readBundle(); + } + + /** @hide */ + @Override + public int describeContents() { + return 0; + } + + /** @hide */ + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mType); + dest.writeBundle(mConfig); + } + + /** @hide */ + public static final Parcelable.Creator CREATOR + = new Parcelable.Creator() { + public CarSensorConfig createFromParcel(Parcel in) { + return new CarSensorConfig(in); + } + + public CarSensorConfig[] newArray(int size) { + return new CarSensorConfig[size]; + } + }; + + /** @hide */ + public CarSensorConfig(int type, Bundle b) { + mType = type; + mConfig = b.deepCopy(); + } + + private void checkType(int type) { + if (mType == type) { + return; + } + throw new UnsupportedOperationException(String.format( + "Invalid sensor type: expected %d, got %d", type, mType)); + } + + /** @hide */ + public Bundle getBundle() { + return mConfig; + } + + /** @hide */ + public int getInt(String key) { + if (mConfig.containsKey(key)) { + return mConfig.getInt(key); + } else { + throw new IllegalArgumentException("SensorType " + mType + + " does not contain key: " + key); + } + } + + /** @hide */ + public int getType() { + return mType; + } + + /** @hide */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getName() + "["); + sb.append("mType: " + mType); + sb.append("mConfig: " + mConfig.toString()); + sb.append("]"); + return sb.toString(); + } +} diff --git a/car-lib/src/android/car/hardware/CarSensorManager.java b/car-lib/src/android/car/hardware/CarSensorManager.java index 796da7f978..e2bce11b78 100644 --- a/car-lib/src/android/car/hardware/CarSensorManager.java +++ b/car-lib/src/android/car/hardware/CarSensorManager.java @@ -25,6 +25,7 @@ import android.car.CarLibLog; import android.car.CarManagerBase; import android.car.CarNotConnectedException; import android.content.Context; +import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; @@ -513,4 +514,28 @@ public final class CarSensorManager implements CarManagerBase { }); } } + + /** + * Get the config data for the given type. + * + * A CarSensorConfig object is returned for every sensor type. However, if there is no + * config, the data will be empty. + * + * @param sensor type to request + * @return CarSensorConfig object + * @throws CarNotConnectedException if the connection to the car service has been lost. + * @hide + */ + public CarSensorConfig getSensorConfig(@SensorType int type) + throws CarNotConnectedException { + assertSensorType(type); + try { + return mService.getSensorConfig(type); + } catch (IllegalStateException e) { + CarApiUtil.checkCarNotConnectedExceptionFromCarService(e); + } catch(RemoteException e) { + handleCarServiceRemoteExceptionAndThrow(e); + } + return new CarSensorConfig(0, Bundle.EMPTY); + } } diff --git a/car-lib/src/android/car/hardware/ICarSensor.aidl b/car-lib/src/android/car/hardware/ICarSensor.aidl index 6f9e3153fc..e943e0f296 100644 --- a/car-lib/src/android/car/hardware/ICarSensor.aidl +++ b/car-lib/src/android/car/hardware/ICarSensor.aidl @@ -16,6 +16,7 @@ package android.car.hardware; +import android.car.hardware.CarSensorConfig; import android.car.hardware.CarSensorEvent; import android.car.hardware.ICarSensorEventListener; @@ -44,4 +45,9 @@ interface ICarSensor { * be affected. */ void unregisterSensorListener(int sensorType, in ICarSensorEventListener callback) = 3; + + /** + * get config flags and config array for the sensor type + */ + CarSensorConfig getSensorConfig(int sensorType) = 4; } diff --git a/car-support-lib/src/android/support/car/hardware/CarSensorConfig.java b/car-support-lib/src/android/support/car/hardware/CarSensorConfig.java new file mode 100644 index 0000000000..3c71e04cc7 --- /dev/null +++ b/car-support-lib/src/android/support/car/hardware/CarSensorConfig.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.support.car.hardware; + +import android.os.Bundle; +import android.support.annotation.RestrictTo; +import java.util.ArrayList; + +import static android.support.annotation.RestrictTo.Scope.GROUP_ID; + +/** + * A CarSensorConfig object corresponds to a single sensor type coming from the car. + * @hide + */ +public class CarSensorConfig { + /** List of property specific mapped elements in bundle for WHEEL_TICK_DISTANCE sensor*/ + /** @hide */ + public final static String WHEEL_TICK_DISTANCE_SUPPORTED_WHEELS = + "android.car.wheelTickDistanceSupportedWhheels"; + /** @hide */ + public final static String WHEEL_TICK_DISTANCE_FRONT_LEFT_UM_PER_TICK = + "android.car.wheelTickDistanceFrontLeftUmPerTick"; + /** @hide */ + public final static String WHEEL_TICK_DISTANCE_FRONT_RIGHT_UM_PER_TICK = + "android.car.wheelTickDistanceFrontRightUmPerTick"; + /** @hide */ + public final static String WHEEL_TICK_DISTANCE_REAR_RIGHT_UM_PER_TICK = + "android.car.wheelTickDistanceRearRightUmPerTick"; + /** @hide */ + public final static String WHEEL_TICK_DISTANCE_REAR_LEFT_UM_PER_TICK = + "android.car.wheelTickDistanceRearLeftUmPerTick"; + + /** Config data stored in Bundle */ + private final Bundle mConfig; + private final int mType; + + private final static int RAW_BUNDLE_SIZE = 4; + private final static int WHEEL_TICK_DISTANCE_BUNDLE_SIZE = 6; + + /** + * Constructs a {@link CarSensorConfig}. Handled by CarSensorManager implementations. + * App developers need not worry about constructing these objects. + * @hide + */ + @RestrictTo(GROUP_ID) + public CarSensorConfig(int type, Bundle in) { + mType = type; + mConfig = in.deepCopy(); + } + + private void checkType(int type) { + if (mType == type) { + return; + } + throw new UnsupportedOperationException(String.format( + "Invalid sensor type: expected %d, got %d", type, mType)); + } + + /** @hide */ + public int getInt(String key) { + if (mConfig.containsKey(key)) { + return mConfig.getInt(key); + } else { + throw new IllegalArgumentException("SensorType " + mType + + " does not contain key: " + key); + } + } + + /** @hide */ + public int getType() { + return mType; + } + + /** @hide */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getName() + "["); + sb.append("mConfig: " + mConfig.toString()); + sb.append("mType: " + mType); + sb.append("]"); + return sb.toString(); + } +} diff --git a/car-support-lib/src/android/support/car/hardware/CarSensorManager.java b/car-support-lib/src/android/support/car/hardware/CarSensorManager.java index f705a9f4e3..8bddce1d0a 100644 --- a/car-support-lib/src/android/support/car/hardware/CarSensorManager.java +++ b/car-support-lib/src/android/support/car/hardware/CarSensorManager.java @@ -280,4 +280,15 @@ public abstract class CarSensorManager implements CarManagerBase { */ public abstract CarSensorEvent getLatestSensorEvent(@SensorType int type) throws CarNotConnectedException; + + /** + * Get the config data for the given type. + * @param sensor type to request + * @return CarSensorConfig object + * @throws CarNotConnectedException if the connection to the car service has been lost. + * @hide + */ + public abstract CarSensorConfig getSensorConfig(@SensorType int type) + throws CarNotConnectedException; + } diff --git a/car-support-lib/src/android/support/car/hardware/CarSensorManagerEmbedded.java b/car-support-lib/src/android/support/car/hardware/CarSensorManagerEmbedded.java index 5fa207cc9f..0fde10ff26 100644 --- a/car-support-lib/src/android/support/car/hardware/CarSensorManagerEmbedded.java +++ b/car-support-lib/src/android/support/car/hardware/CarSensorManagerEmbedded.java @@ -154,6 +154,16 @@ public class CarSensorManagerEmbedded extends CarSensorManager { } } + @Override + public CarSensorConfig getSensorConfig(@SensorType int type) + throws CarNotConnectedException { + try { + return convert(mManager.getSensorConfig(type)); + } catch (android.car.CarNotConnectedException e) { + throw new CarNotConnectedException(e); + } + } + @Override public void onCarDisconnected() { //nothing to do @@ -176,6 +186,13 @@ public class CarSensorManagerEmbedded extends CarSensorManager { event.intValues, event.longValues); } + private static CarSensorConfig convert(android.car.hardware.CarSensorConfig cfg) { + if (cfg == null) { + return null; + } + return new CarSensorConfig(cfg.getType(), cfg.getBundle()); + } + private static class OnSensorChangedListenerProxy implements android.car.hardware.CarSensorManager.OnSensorChangedListener { diff --git a/service/src/com/android/car/CarSensorService.java b/service/src/com/android/car/CarSensorService.java index 44a33b4bae..171a8c4bf4 100644 --- a/service/src/com/android/car/CarSensorService.java +++ b/service/src/com/android/car/CarSensorService.java @@ -17,6 +17,7 @@ package com.android.car; import android.car.Car; +import android.car.hardware.CarSensorConfig; import android.car.hardware.CarSensorEvent; import android.car.hardware.CarSensorManager; import android.car.hardware.ICarSensor; @@ -565,6 +566,22 @@ public class CarSensorService extends ICarSensor.Stub } } + @Override + public CarSensorConfig getSensorConfig(int sensorType) { + if (Binder.getCallingUid() != Process.myUid()) { + switch (getSensorPermission(sensorType)) { + case PackageManager.PERMISSION_DENIED: + throw new SecurityException("client does not have permission:" + + getPermissionName(sensorType) + + " pid:" + Binder.getCallingPid() + + " uid:" + Binder.getCallingUid()); + case PackageManager.PERMISSION_GRANTED: + break; + } + } + return(mSensorHal.getSensorConfig(sensorType)); + } + private void stopSensor(SensorRecord record, int sensorType) { if (Log.isLoggable(CarLog.TAG_SENSOR, Log.DEBUG)) { Log.d(CarLog.TAG_SENSOR, "stopSensor " + sensorType); diff --git a/service/src/com/android/car/hal/SensorHalService.java b/service/src/com/android/car/hal/SensorHalService.java index 2b84fc4ecf..cf29f810cf 100644 --- a/service/src/com/android/car/hal/SensorHalService.java +++ b/service/src/com/android/car/hal/SensorHalService.java @@ -19,6 +19,7 @@ package com.android.car.hal; import static java.lang.Integer.toHexString; import android.annotation.Nullable; +import android.car.hardware.CarSensorConfig; import android.car.hardware.CarSensorEvent; import android.car.hardware.CarSensorManager; import android.hardware.automotive.vehicle.V2_0.VehicleGear; @@ -29,11 +30,13 @@ import android.hardware.automotive.vehicle.V2_1.VehicleProperty; import android.hardware.automotive.vehicle.V2_0.VehiclePropertyAccess; import android.hardware.automotive.vehicle.V2_0.VehiclePropertyChangeMode; import android.hardware.automotive.vehicle.V2_0.VehiclePropertyType; +import android.os.Bundle; import android.util.Log; import android.util.SparseIntArray; import com.android.car.CarLog; import com.android.car.CarSensorEventFactory; import java.io.PrintWriter; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -50,6 +53,7 @@ public class SensorHalService extends SensorHalServiceBase { public interface SensorListener { /** * Sensor events are available. + * * @param events */ void onSensorEvents(List events); @@ -57,44 +61,44 @@ public class SensorHalService extends SensorHalServiceBase { // Manager property Id to HAL property Id mapping. private final static ManagerToHalPropIdMap mManagerToHalPropIdMap = - ManagerToHalPropIdMap.create( - CarSensorManager.SENSOR_TYPE_CAR_SPEED, VehicleProperty.PERF_VEHICLE_SPEED, - CarSensorManager.SENSOR_TYPE_RPM, VehicleProperty.ENGINE_RPM, - CarSensorManager.SENSOR_TYPE_ODOMETER, VehicleProperty.PERF_ODOMETER, - CarSensorManager.SENSOR_TYPE_GEAR, VehicleProperty.GEAR_SELECTION, - CarSensorManager.SENSOR_TYPE_NIGHT, VehicleProperty.NIGHT_MODE, - CarSensorManager.SENSOR_TYPE_PARKING_BRAKE, VehicleProperty.PARKING_BRAKE_ON, - CarSensorManager.SENSOR_TYPE_DRIVING_STATUS, VehicleProperty.DRIVING_STATUS, - CarSensorManager.SENSOR_TYPE_FUEL_LEVEL, VehicleProperty.FUEL_LEVEL_LOW, - CarSensorManager.SENSOR_TYPE_IGNITION_STATE, VehicleProperty.IGNITION_STATE, - CarSensorManager.SENSOR_TYPE_WHEEL_TICK_DISTANCE, VehicleProperty.WHEEL_TICK, - CarSensorManager.SENSOR_TYPE_ABS_ACTIVE, VehicleProperty.ABS_ACTIVE, - CarSensorManager.SENSOR_TYPE_TRACTION_CONTROL_ACTIVE, - VehicleProperty.TRACTION_CONTROL_ACTIVE - ); + ManagerToHalPropIdMap.create( + CarSensorManager.SENSOR_TYPE_CAR_SPEED, VehicleProperty.PERF_VEHICLE_SPEED, + CarSensorManager.SENSOR_TYPE_RPM, VehicleProperty.ENGINE_RPM, + CarSensorManager.SENSOR_TYPE_ODOMETER, VehicleProperty.PERF_ODOMETER, + CarSensorManager.SENSOR_TYPE_GEAR, VehicleProperty.GEAR_SELECTION, + CarSensorManager.SENSOR_TYPE_NIGHT, VehicleProperty.NIGHT_MODE, + CarSensorManager.SENSOR_TYPE_PARKING_BRAKE, VehicleProperty.PARKING_BRAKE_ON, + CarSensorManager.SENSOR_TYPE_DRIVING_STATUS, VehicleProperty.DRIVING_STATUS, + CarSensorManager.SENSOR_TYPE_FUEL_LEVEL, VehicleProperty.FUEL_LEVEL_LOW, + CarSensorManager.SENSOR_TYPE_IGNITION_STATE, VehicleProperty.IGNITION_STATE, + CarSensorManager.SENSOR_TYPE_WHEEL_TICK_DISTANCE, VehicleProperty.WHEEL_TICK, + CarSensorManager.SENSOR_TYPE_ABS_ACTIVE, VehicleProperty.ABS_ACTIVE, + CarSensorManager.SENSOR_TYPE_TRACTION_CONTROL_ACTIVE, + VehicleProperty.TRACTION_CONTROL_ACTIVE + ); private final static SparseIntArray mMgrGearToHalMap = initSparseIntArray( - VehicleGear.GEAR_NEUTRAL, CarSensorEvent.GEAR_NEUTRAL, - VehicleGear.GEAR_REVERSE, CarSensorEvent.GEAR_REVERSE, - VehicleGear.GEAR_PARK, CarSensorEvent.GEAR_PARK, - VehicleGear.GEAR_DRIVE, CarSensorEvent.GEAR_DRIVE, - VehicleGear.GEAR_LOW, CarSensorEvent.GEAR_FIRST, // Also GEAR_1 - the value is the same. - VehicleGear.GEAR_2, CarSensorEvent.GEAR_SECOND, - VehicleGear.GEAR_3, CarSensorEvent.GEAR_THIRD, - VehicleGear.GEAR_4, CarSensorEvent.GEAR_FOURTH, - VehicleGear.GEAR_5, CarSensorEvent.GEAR_FIFTH, - VehicleGear.GEAR_6, CarSensorEvent.GEAR_SIXTH, - VehicleGear.GEAR_7, CarSensorEvent.GEAR_SEVENTH, - VehicleGear.GEAR_8, CarSensorEvent.GEAR_EIGHTH, - VehicleGear.GEAR_9, CarSensorEvent.GEAR_NINTH); + VehicleGear.GEAR_NEUTRAL, CarSensorEvent.GEAR_NEUTRAL, + VehicleGear.GEAR_REVERSE, CarSensorEvent.GEAR_REVERSE, + VehicleGear.GEAR_PARK, CarSensorEvent.GEAR_PARK, + VehicleGear.GEAR_DRIVE, CarSensorEvent.GEAR_DRIVE, + VehicleGear.GEAR_LOW, CarSensorEvent.GEAR_FIRST, // Also GEAR_1 - the value is the same. + VehicleGear.GEAR_2, CarSensorEvent.GEAR_SECOND, + VehicleGear.GEAR_3, CarSensorEvent.GEAR_THIRD, + VehicleGear.GEAR_4, CarSensorEvent.GEAR_FOURTH, + VehicleGear.GEAR_5, CarSensorEvent.GEAR_FIFTH, + VehicleGear.GEAR_6, CarSensorEvent.GEAR_SIXTH, + VehicleGear.GEAR_7, CarSensorEvent.GEAR_SEVENTH, + VehicleGear.GEAR_8, CarSensorEvent.GEAR_EIGHTH, + VehicleGear.GEAR_9, CarSensorEvent.GEAR_NINTH); private final static SparseIntArray mMgrIgnitionStateToHalMap = initSparseIntArray( - VehicleIgnitionState.UNDEFINED, CarSensorEvent.IGNITION_STATE_UNDEFINED, - VehicleIgnitionState.LOCK, CarSensorEvent.IGNITION_STATE_LOCK, - VehicleIgnitionState.OFF, CarSensorEvent.IGNITION_STATE_OFF, - VehicleIgnitionState.ACC, CarSensorEvent.IGNITION_STATE_ACC, - VehicleIgnitionState.ON, CarSensorEvent.IGNITION_STATE_ON, - VehicleIgnitionState.START, CarSensorEvent.IGNITION_STATE_START); + VehicleIgnitionState.UNDEFINED, CarSensorEvent.IGNITION_STATE_UNDEFINED, + VehicleIgnitionState.LOCK, CarSensorEvent.IGNITION_STATE_LOCK, + VehicleIgnitionState.OFF, CarSensorEvent.IGNITION_STATE_OFF, + VehicleIgnitionState.ACC, CarSensorEvent.IGNITION_STATE_ACC, + VehicleIgnitionState.ON, CarSensorEvent.IGNITION_STATE_ON, + VehicleIgnitionState.START, CarSensorEvent.IGNITION_STATE_START); private SensorListener mSensorListener; @@ -102,15 +106,17 @@ public class SensorHalService extends SensorHalServiceBase { @Override public void init() { + VehiclePropConfig config; // Populate internal values if available - VehiclePropConfig config = mSensorToPropConfig.get( - CarSensorManager.SENSOR_TYPE_WHEEL_TICK_DISTANCE); + synchronized (this) { + config = mSensorToPropConfig.get(CarSensorManager.SENSOR_TYPE_WHEEL_TICK_DISTANCE); + } if (config == null) { Log.e(TAG, "init: unable to get property config for SENSOR_TYPE_WHEEL_TICK_DISTANCE"); } else { - for (int i=0; i<4; i++) { - // ConfigArray starts with Wheels enum at idx 0 - mMicrometersPerWheelTick[i] = config.configArray.get(i+1); + for (int i = 0; i < 4; i++) { + mMicrometersPerWheelTick[i] = config.configArray.get(i + + INDEX_WHEEL_DISTANCE_FRONT_LEFT); } } super.init(); @@ -137,6 +143,7 @@ public class SensorHalService extends SensorHalServiceBase { // Should be used only inside handleHalEvents method. private final LinkedList mEventsToDispatch = new LinkedList<>(); + @Override public void handleHalEvents(List values) { for (VehiclePropValue v : values) { @@ -165,7 +172,7 @@ public class SensorHalService extends SensorHalServiceBase { mgrValue = mMgrGearToHalMap.get(halValue, -1); break; case VehicleProperty.IGNITION_STATE: - mgrValue = mMgrIgnitionStateToHalMap.get(halValue, -1); + mgrValue = mMgrIgnitionStateToHalMap.get(halValue, -1); default: break; // Do nothing } @@ -192,7 +199,7 @@ public class SensorHalService extends SensorHalServiceBase { break; case VehiclePropertyType.INT32: Integer mgrVal = mapHalEnumValueToMgr(property, v.value.int32Values.get(0)); - event = mgrVal == null ? null + event = mgrVal == null ? null : CarSensorEventFactory.createIntEvent(sensorType, v.timestamp, mgrVal); break; case VehiclePropertyType.FLOAT: @@ -283,4 +290,50 @@ public class SensorHalService extends SensorHalServiceBase { } return map; } -} + + private static final int INDEX_WHEEL_DISTANCE_ENABLE_FLAG = 0; + private static final int INDEX_WHEEL_DISTANCE_FRONT_LEFT = 1; + private static final int INDEX_WHEEL_DISTANCE_FRONT_RIGHT = 2; + private static final int INDEX_WHEEL_DISTANCE_REAR_RIGHT = 3; + private static final int INDEX_WHEEL_DISTANCE_REAR_LEFT = 4; + private static final int WHEEL_TICK_DISTANCE_BUNDLE_SIZE = 6; + + private Bundle createWheelDistanceTickBundle(ArrayList configArray) { + Bundle b = new Bundle(WHEEL_TICK_DISTANCE_BUNDLE_SIZE); + b.putInt(CarSensorConfig.WHEEL_TICK_DISTANCE_SUPPORTED_WHEELS, + configArray.get(INDEX_WHEEL_DISTANCE_ENABLE_FLAG)); + b.putInt(CarSensorConfig.WHEEL_TICK_DISTANCE_FRONT_LEFT_UM_PER_TICK, + configArray.get(INDEX_WHEEL_DISTANCE_FRONT_LEFT)); + b.putInt(CarSensorConfig.WHEEL_TICK_DISTANCE_FRONT_RIGHT_UM_PER_TICK, + configArray.get(INDEX_WHEEL_DISTANCE_FRONT_RIGHT)); + b.putInt(CarSensorConfig.WHEEL_TICK_DISTANCE_REAR_RIGHT_UM_PER_TICK, + configArray.get(INDEX_WHEEL_DISTANCE_REAR_RIGHT)); + b.putInt(CarSensorConfig.WHEEL_TICK_DISTANCE_REAR_LEFT_UM_PER_TICK, + configArray.get(INDEX_WHEEL_DISTANCE_REAR_LEFT)); + return b; + } + + + public CarSensorConfig getSensorConfig(int sensorType) { + VehiclePropConfig cfg; + synchronized (this) { + cfg = mSensorToPropConfig.get(sensorType); + } + if (cfg == null) { + /* Invalid sensor type. */ + throw new IllegalArgumentException("Unknown sensorType = " + sensorType); + } else { + Bundle b; + switch(sensorType) { + case CarSensorManager.SENSOR_TYPE_WHEEL_TICK_DISTANCE: + b = createWheelDistanceTickBundle(cfg.configArray); + break; + default: + /* Unhandled config. Create empty bundle */ + b = Bundle.EMPTY; + break; + } + return new CarSensorConfig(sensorType, b); + } + } +} \ No newline at end of file diff --git a/tests/EmbeddedKitchenSinkApp/res/values/strings.xml b/tests/EmbeddedKitchenSinkApp/res/values/strings.xml index 66ff16d608..5e66a53c03 100644 --- a/tests/EmbeddedKitchenSinkApp/res/values/strings.xml +++ b/tests/EmbeddedKitchenSinkApp/res/values/strings.xml @@ -175,6 +175,7 @@ GPS Satellites[%1$s]: inView: %2$s, inUse: %3$s. %4$s (%1$s): usedInFix: %2$s, prn: %3$s, snr: %4$s, azimuth: %5$s, elevation: %6$s Wheel Distance[%1$s]: reset=%2$s, FL=%3$s, FR=%4$s, RL=%5$s, RR=%6$s + Wheel Distance Config: Wheels=%1$s, FL=%2$s, FR=%3$s, RL=%4$s, RR=%5$s ABS[%1$s]: isActive=%2$s Traction Control[%1$s]: isActive=%2$s diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/sensor/SensorsTestFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/sensor/SensorsTestFragment.java index 082a3f0a6b..d502c75901 100644 --- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/sensor/SensorsTestFragment.java +++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/sensor/SensorsTestFragment.java @@ -24,6 +24,7 @@ import android.location.Location; import android.os.Bundle; import android.os.Handler; import android.support.car.CarNotConnectedException; +import android.support.car.hardware.CarSensorConfig; import android.support.car.hardware.CarSensorEvent; import android.support.car.hardware.CarSensorManager; import android.support.v4.app.Fragment; @@ -285,6 +286,19 @@ public class SensorsTestFragment extends Fragment { getTimestamp(event), mNaString, mNaString, mNaString, mNaString, mNaString)); } + // Get the config data + try { + CarSensorConfig c = mSensorManager.getSensorConfig( + CarSensorManager.SENSOR_TYPE_WHEEL_TICK_DISTANCE); + summary.add(getContext().getString(R.string.sensor_wheel_ticks_cfg, + c.getInt(CarSensorConfig.WHEEL_TICK_DISTANCE_SUPPORTED_WHEELS), + c.getInt(CarSensorConfig.WHEEL_TICK_DISTANCE_FRONT_LEFT_UM_PER_TICK), + c.getInt(CarSensorConfig.WHEEL_TICK_DISTANCE_FRONT_RIGHT_UM_PER_TICK), + c.getInt(CarSensorConfig.WHEEL_TICK_DISTANCE_REAR_LEFT_UM_PER_TICK), + c.getInt(CarSensorConfig.WHEEL_TICK_DISTANCE_REAR_RIGHT_UM_PER_TICK))); + } catch (CarNotConnectedException e) { + Log.e(TAG, "Car not connected or not supported", e); + } break; case CarSensorManager.SENSOR_TYPE_ABS_ACTIVE: summary.add(getContext().getString(R.string.sensor_abs_is_active, -- cgit v1.2.3 From bb9ebde20c351863a04190896142c63be88284fb Mon Sep 17 00:00:00 2001 From: Lujiang Xue Date: Mon, 7 Aug 2017 14:18:32 -0700 Subject: remove Map monitoring from kitchenSink Bug: 64391322 Test: build and flash Change-Id: Ie99928fc9ec7e6b5a063e6afae406ba42b5d8295 --- tests/EmbeddedKitchenSinkApp/AndroidManifest.xml | 8 ----- .../car/kitchensink/bluetooth/MapReceiver.java | 37 ---------------------- 2 files changed, 45 deletions(-) delete mode 100644 tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/bluetooth/MapReceiver.java diff --git a/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml b/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml index 2f7279802b..2a968987a9 100644 --- a/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml +++ b/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml @@ -102,13 +102,5 @@ - - - - - - - diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/bluetooth/MapReceiver.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/bluetooth/MapReceiver.java deleted file mode 100644 index e0d1ca06bc..0000000000 --- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/bluetooth/MapReceiver.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.android.car.kitchensink.bluetooth; - -import android.bluetooth.BluetoothMapClient; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.util.Log; -import android.widget.Toast; - -public class MapReceiver extends BroadcastReceiver { - private static final String TAG = "CAR.BLUETOOTH.KS"; - @Override - public void onReceive(Context context, Intent intent) { - Log.d(TAG, "MAP onReceive"); - String action = intent.getAction(); - if (action.equals(BluetoothMapClient.ACTION_MESSAGE_RECEIVED)) { - Toast.makeText(context, intent.getStringExtra(android.content.Intent.EXTRA_TEXT), - Toast.LENGTH_LONG).show(); - } - } -} -- cgit v1.2.3 From b4dc215271f5eaa2fe14af42aabf00e925a8ebf5 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Tue, 8 Aug 2017 07:48:36 -0700 Subject: Bluetooth: move AIDL files related to bluetooth into system/bt (3/3) This patch moves *.aidl files from frameworks/base/core/java/android/bluetooth into system/bt/binder. This is in preparation to convert the Bluetooth deamon into native implementation piece by piece. In order to do that, one must have C++ header files, and paths to them with AIDL files, and */java/* folder didn't seem as proper place for that. Additionally, keeping AIDL files out of framework/base will not require creating dependency on this huge project, which should help keeping the compilation fast. Test: compilation test Change-Id: I75b898380bd0a2f22a8495d8e10156f1efa64495 --- car-lib/Android.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/car-lib/Android.mk b/car-lib/Android.mk index a07e940376..53be4a761b 100644 --- a/car-lib/Android.mk +++ b/car-lib/Android.mk @@ -37,6 +37,7 @@ else car_lib_sources += $(call all-java-files-under, src_feature_current) endif car_lib_sources += $(call all-Iaidl-files-under, src) +LOCAL_AIDL_INCLUDES += system/bt/binder LOCAL_SRC_FILES := $(car_lib_sources) @@ -65,6 +66,7 @@ include $(CLEAR_VARS) LOCAL_MODULE := android.car7 LOCAL_SRC_FILES := $(car_lib_sources) LOCAL_JAVA_LANGUAGE_VERSION := 1.7 +LOCAL_AIDL_INCLUDES += system/bt/binder ifeq ($(EMMA_INSTRUMENT_FRAMEWORK),true) LOCAL_EMMA_INSTRUMENT := true -- cgit v1.2.3 From d7870ff24679b22e33afc9f8a6180b0504afb8eb Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Tue, 8 Aug 2017 07:48:36 -0700 Subject: Bluetooth: move AIDL files related to Bluetooth into system/bt (3/3) This patch moves *.aidl files from frameworks/base/core/java/android/bluetooth into system/bt/binder. This is in preparation to convert the Bluetooth deamon into native implementation piece by piece. In order to do that, one must have C++ header files, and paths to them with AIDL files, and */java/* folder didn't seem as proper place for that. Additionally, keeping AIDL files out of framework/base will not require creating dependency on this huge project, which should help keeping the compilation fast. Test: compilation test Change-Id: I75b898380bd0a2f22a8495d8e10156f1efa64495 Merged-In: I75b898380bd0a2f22a8495d8e10156f1efa64495 (cherry picked from commit b4dc215271f5eaa2fe14af42aabf00e925a8ebf5) --- bluetooth/bt-map-client-lib/Android.mk | 1 + car-lib/Android.mk | 1 + 2 files changed, 2 insertions(+) diff --git a/bluetooth/bt-map-client-lib/Android.mk b/bluetooth/bt-map-client-lib/Android.mk index 4970d02c11..4bfefe3896 100644 --- a/bluetooth/bt-map-client-lib/Android.mk +++ b/bluetooth/bt-map-client-lib/Android.mk @@ -21,6 +21,7 @@ LOCAL_MODULE := bt-map-client-lib LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-subdir-Iaidl-files) +LOCAL_AIDL_INCLUDES += system/bt/binder LOCAL_JAVA_LIBRARIES := \ javax.obex \ diff --git a/car-lib/Android.mk b/car-lib/Android.mk index e1f4105c49..7a1d07c896 100644 --- a/car-lib/Android.mk +++ b/car-lib/Android.mk @@ -25,6 +25,7 @@ LOCAL_MODULE := android.car LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-Iaidl-files-under, src) +LOCAL_AIDL_INCLUDES += system/bt/binder include $(BUILD_JAVA_LIBRARY) -- cgit v1.2.3 From 39cfdea1817951d36b08d9ac7630b73930d3ab87 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Tue, 8 Aug 2017 07:48:36 -0700 Subject: olve merge conflicts of d7870ff24679b22e33afc9f8a6180b0504afb8eb to stage-aosp-master Test: this fixes merge conflict that I skipped Change-Id: I75b898380bd0a2f22a8495d8e10156f1efa64496 Merged-In: I75b898380bd0a2f22a8495d8e10156f1efa64495 --- car-lib/Android.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/car-lib/Android.mk b/car-lib/Android.mk index a07e940376..53be4a761b 100644 --- a/car-lib/Android.mk +++ b/car-lib/Android.mk @@ -37,6 +37,7 @@ else car_lib_sources += $(call all-java-files-under, src_feature_current) endif car_lib_sources += $(call all-Iaidl-files-under, src) +LOCAL_AIDL_INCLUDES += system/bt/binder LOCAL_SRC_FILES := $(car_lib_sources) @@ -65,6 +66,7 @@ include $(CLEAR_VARS) LOCAL_MODULE := android.car7 LOCAL_SRC_FILES := $(car_lib_sources) LOCAL_JAVA_LANGUAGE_VERSION := 1.7 +LOCAL_AIDL_INCLUDES += system/bt/binder ifeq ($(EMMA_INSTRUMENT_FRAMEWORK),true) LOCAL_EMMA_INSTRUMENT := true -- cgit v1.2.3 From 3c6e344ebf379c2a660b2e66bb87a0f1b7ae548f Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Tue, 8 Aug 2017 07:48:36 -0700 Subject: Bluetooth: move AIDL files related to bluetooth into system/bt (3/3) This patch moves *.aidl files from frameworks/base/core/java/android/bluetooth into system/bt/binder. This is in preparation to convert the Bluetooth deamon into native implementation piece by piece. In order to do that, one must have C++ header files, and paths to them with AIDL files, and */java/* folder didn't seem as proper place for that. Additionally, keeping AIDL files out of framework/base will not require creating dependency on this huge project, which should help keeping the compilation fast. Test: compilation test Change-Id: I75b898380bd0a2f22a8495d8e10156f1efa64495 --- car-lib/Android.mk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/car-lib/Android.mk b/car-lib/Android.mk index a07e940376..53be4a761b 100644 --- a/car-lib/Android.mk +++ b/car-lib/Android.mk @@ -37,6 +37,7 @@ else car_lib_sources += $(call all-java-files-under, src_feature_current) endif car_lib_sources += $(call all-Iaidl-files-under, src) +LOCAL_AIDL_INCLUDES += system/bt/binder LOCAL_SRC_FILES := $(car_lib_sources) @@ -65,6 +66,7 @@ include $(CLEAR_VARS) LOCAL_MODULE := android.car7 LOCAL_SRC_FILES := $(car_lib_sources) LOCAL_JAVA_LANGUAGE_VERSION := 1.7 +LOCAL_AIDL_INCLUDES += system/bt/binder ifeq ($(EMMA_INSTRUMENT_FRAMEWORK),true) LOCAL_EMMA_INSTRUMENT := true -- cgit v1.2.3 From 4a79a38b5f73596f39ea41794c6bd6d9bde12ce9 Mon Sep 17 00:00:00 2001 From: Keun-young Park Date: Thu, 10 Aug 2017 18:19:14 -0700 Subject: reflect rename of TimingsTraceLog bug: 64569080 Test: build Change-Id: I6f1c4547645761cd613b4fe6158fb600c7c4026c --- service/src/com/android/car/ICarImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/service/src/com/android/car/ICarImpl.java b/service/src/com/android/car/ICarImpl.java index c412b97e14..5b01bcf089 100644 --- a/service/src/com/android/car/ICarImpl.java +++ b/service/src/com/android/car/ICarImpl.java @@ -28,9 +28,9 @@ import android.os.Binder; import android.os.IBinder; import android.os.Process; import android.os.Trace; -import android.util.BootTimingsTraceLog; import android.util.Log; import android.util.Slog; +import android.util.TimingsTraceLog; import com.android.car.cluster.InstrumentClusterService; import com.android.car.hal.VehicleHal; import com.android.car.internal.FeatureConfiguration; @@ -81,7 +81,7 @@ public class ICarImpl extends ICar.Stub { private static final String TAG = "ICarImpl"; private static final String VHAL_TIMING_TAG = "VehicleHalTiming"; - private static final BootTimingsTraceLog mBootTiming = new BootTimingsTraceLog(VHAL_TIMING_TAG, + private static final TimingsTraceLog mBootTiming = new TimingsTraceLog(VHAL_TIMING_TAG, Trace.TRACE_TAG_HAL); /** Test only service. Populate it only when necessary. */ -- cgit v1.2.3 From bcd5655d0afcf64a7439af8e3e5d6a37045d4ec4 Mon Sep 17 00:00:00 2001 From: Agranee Date: Fri, 11 Aug 2017 12:45:56 -0700 Subject: KitchenSink Bluetooth Hold call button Add hold call button to bluetooth headset fragment Bug: 63412812 Test: Start a Call with a phone/telco that supports hold and hold a call Change-Id: I8132a20bf7ff1f28b077880fc2e90602b3e7abd7 --- .../res/layout/bluetooth_headset.xml | 5 ++++ .../EmbeddedKitchenSinkApp/res/values/strings.xml | 1 + .../bluetooth/BluetoothHeadsetFragment.java | 31 +++++++++++++++++++--- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/tests/EmbeddedKitchenSinkApp/res/layout/bluetooth_headset.xml b/tests/EmbeddedKitchenSinkApp/res/layout/bluetooth_headset.xml index 0547a8f4f1..5dbefc10e3 100644 --- a/tests/EmbeddedKitchenSinkApp/res/layout/bluetooth_headset.xml +++ b/tests/EmbeddedKitchenSinkApp/res/layout/bluetooth_headset.xml @@ -57,4 +57,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/bluetooth_quiet_mode_enable"/> +