1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.support.car.hardware;
18
19import android.support.car.CarNotConnectedException;
20
21import java.util.LinkedList;
22
23/**
24 *  @hide
25 */
26public class CarSensorManagerEmbedded extends CarSensorManager {
27
28    private final android.car.hardware.CarSensorManager mManager;
29    private final LinkedList<CarSensorEventListenerProxy> mListeners = new LinkedList<>();
30
31    public CarSensorManagerEmbedded(Object manager) {
32        mManager = (android.car.hardware.CarSensorManager) manager;
33    }
34
35    @Override
36    public int[] getSupportedSensors() throws CarNotConnectedException {
37        try {
38            return mManager.getSupportedSensors();
39        } catch (android.car.CarNotConnectedException e) {
40            throw new CarNotConnectedException(e);
41        }
42    }
43
44    @Override
45    public boolean isSensorSupported(int sensorType) throws CarNotConnectedException {
46        try {
47            return mManager.isSensorSupported(sensorType);
48        } catch (android.car.CarNotConnectedException e) {
49            throw new CarNotConnectedException(e);
50        }
51    }
52
53    @Override
54    public boolean registerListener(CarSensorEventListener listener, int sensorType,
55            int rate) throws CarNotConnectedException, IllegalArgumentException {
56        CarSensorEventListenerProxy proxy = null;
57        synchronized (this) {
58            proxy = findListenerLocked(listener);
59            if (proxy == null) {
60                proxy = new CarSensorEventListenerProxy(listener, sensorType);
61            } else {
62                proxy.sensors |= sensorType;
63            }
64        }
65        try {
66            return mManager.registerListener(proxy, sensorType, rate);
67        } catch (android.car.CarNotConnectedException e) {
68            throw new CarNotConnectedException(e);
69        }
70    }
71
72    @Override
73    public void unregisterListener(CarSensorEventListener listener)
74            throws CarNotConnectedException {
75        CarSensorEventListenerProxy proxy = null;
76        synchronized (this) {
77            proxy = findListenerLocked(listener);
78            if (proxy == null) {
79                return;
80            }
81            mListeners.remove(proxy);
82        }
83        try {
84            mManager.unregisterListener(proxy);
85        } catch (android.car.CarNotConnectedException e) {
86            throw new CarNotConnectedException(e);
87        }
88    }
89
90    @Override
91    public void unregisterListener(CarSensorEventListener listener, int sensorType)
92            throws CarNotConnectedException {
93        CarSensorEventListenerProxy proxy = null;
94        synchronized (this) {
95            proxy = findListenerLocked(listener);
96            if (proxy == null) {
97                return;
98            }
99            proxy.sensors &= ~sensorType;
100            if (proxy.sensors == 0) {
101                mListeners.remove(proxy);
102            }
103        }
104        try {
105            mManager.unregisterListener(proxy, sensorType);
106        } catch (android.car.CarNotConnectedException e) {
107            throw new CarNotConnectedException(e);
108        }
109    }
110
111    @Override
112    public CarSensorEvent getLatestSensorEvent(int type) throws CarNotConnectedException {
113        try {
114            return convert(mManager.getLatestSensorEvent(type));
115        } catch (android.car.CarNotConnectedException e) {
116            throw new CarNotConnectedException(e);
117        }
118    }
119
120    @Override
121    public void onCarDisconnected() {
122        //nothing to do
123    }
124
125    private CarSensorEventListenerProxy findListenerLocked(CarSensorEventListener listener) {
126        for (CarSensorEventListenerProxy proxy : mListeners) {
127            if (proxy.listener == listener) {
128                return proxy;
129            }
130        }
131        return null;
132    }
133
134    private static CarSensorEvent convert(android.car.hardware.CarSensorEvent event) {
135        if (event == null) {
136            return null;
137        }
138        return new CarSensorEvent(event.sensorType, event.timeStampNs, event.floatValues,
139                event.intValues);
140    }
141
142    private static class CarSensorEventListenerProxy implements
143            android.car.hardware.CarSensorManager.CarSensorEventListener {
144
145        public final CarSensorEventListener listener;
146        public int sensors;
147
148        public CarSensorEventListenerProxy(CarSensorEventListener listener, int sensors) {
149            this.listener = listener;
150            this.sensors = sensors;
151        }
152
153        @Override
154        public void onSensorChanged(android.car.hardware.CarSensorEvent event) {
155            CarSensorEvent newEvent = convert(event);
156            listener.onSensorChanged(newEvent);
157        }
158    }
159}
160