1e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park/*
2e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * Copyright (C) 2016 The Android Open Source Project
3e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park *
4e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * Licensed under the Apache License, Version 2.0 (the "License");
5e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * you may not use this file except in compliance with the License.
6e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * You may obtain a copy of the License at
7e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park *
8e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park *      http://www.apache.org/licenses/LICENSE-2.0
9e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park *
10e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * Unless required by applicable law or agreed to in writing, software
11e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * distributed under the License is distributed on an "AS IS" BASIS,
12e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * See the License for the specific language governing permissions and
14e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park * limitations under the License.
15e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park */
16e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park
17e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkpackage android.support.car.hardware;
18e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park
197bd39e929390e754c96e2792efe0deac7b3841e6Anthony Chenimport static androidx.annotation.RestrictTo.Scope.GROUP_ID;
207bd39e929390e754c96e2792efe0deac7b3841e6Anthony Chen
21f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkivimport android.content.Context;
22e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport android.support.car.CarNotConnectedException;
237bd39e929390e754c96e2792efe0deac7b3841e6Anthony Chen
247bd39e929390e754c96e2792efe0deac7b3841e6Anthony Chenimport androidx.annotation.RestrictTo;
257bd39e929390e754c96e2792efe0deac7b3841e6Anthony Chen
26f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkivimport java.util.Collection;
27f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkivimport java.util.HashSet;
28e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport java.util.LinkedList;
29f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkivimport java.util.Set;
30f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv
31e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park/**
32e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park *  @hide
33e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park */
34141349407981da8a88f61c0b906240a1c3603ef7Keun-young Park@RestrictTo(GROUP_ID)
35e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkpublic class CarSensorManagerEmbedded extends CarSensorManager {
36f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv    private static final String TAG = "CarSensorsProxy";
37e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park
38e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    private final android.car.hardware.CarSensorManager mManager;
39f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv    private final CarSensorsProxy mCarSensorsProxy;
40d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup    private final LinkedList<OnSensorChangedListenerProxy> mListeners = new LinkedList<>();
41e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park
42f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv    public CarSensorManagerEmbedded(Object manager, Context context) {
43e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        mManager = (android.car.hardware.CarSensorManager) manager;
44d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup        mCarSensorsProxy = new CarSensorsProxy(this, context);
45e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    }
46e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park
47e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    @Override
48e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    public int[] getSupportedSensors() throws CarNotConnectedException {
49e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        try {
50f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv            Set<Integer> sensorsSet = new HashSet<Integer>();
51f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv            for (Integer sensor : mManager.getSupportedSensors()) {
52f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv                sensorsSet.add(sensor);
53f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv            }
54f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv            for (Integer proxySensor : mCarSensorsProxy.getSupportedSensors()) {
55f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv                sensorsSet.add(proxySensor);
56f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv            }
57f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv            return toIntArray(sensorsSet);
58e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        } catch (android.car.CarNotConnectedException e) {
59e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            throw new CarNotConnectedException(e);
60e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        }
61e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    }
62e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park
63f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv    private static int[] toIntArray(Collection<Integer> collection) {
64f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv        int len = collection.size();
65f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv        int[] arr = new int[len];
66f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv        int arrIndex = 0;
67f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv        for (Integer item : collection) {
68f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv            arr[arrIndex] = item;
69f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv            arrIndex++;
70f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv        }
71f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv        return arr;
72f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv    }
73f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv
74e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    @Override
75e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    public boolean isSensorSupported(int sensorType) throws CarNotConnectedException {
76e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        try {
77f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv            return mManager.isSensorSupported(sensorType)
78f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv                    || mCarSensorsProxy.isSensorSupported(sensorType);
79f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv        } catch (android.car.CarNotConnectedException e) {
80f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv            throw new CarNotConnectedException(e);
81f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv        }
82f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv    }
83f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv
84f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv    private boolean isSensorProxied(int sensorType) throws CarNotConnectedException {
85f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv        try {
86f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv            return !mManager.isSensorSupported(sensorType)
87f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv                    && mCarSensorsProxy.isSensorSupported(sensorType);
88e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        } catch (android.car.CarNotConnectedException e) {
89e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            throw new CarNotConnectedException(e);
90e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        }
91e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    }
92e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park
93e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    @Override
94d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup    public boolean addListener(OnSensorChangedListener listener, int sensorType,
95e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            int rate) throws CarNotConnectedException, IllegalArgumentException {
96f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv        if (isSensorProxied(sensorType)) {
97f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv            return mCarSensorsProxy.registerSensorListener(listener, sensorType, rate);
98f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv        }
99d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup        OnSensorChangedListenerProxy proxy = null;
100e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        synchronized (this) {
101e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            proxy = findListenerLocked(listener);
102e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            if (proxy == null) {
103d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup                proxy = new OnSensorChangedListenerProxy(listener, sensorType, this);
104f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv                mListeners.add(proxy);
105e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            } else {
106f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv                proxy.sensors.add(sensorType);
107e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            }
108e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        }
109e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        try {
110e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            return mManager.registerListener(proxy, sensorType, rate);
111e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        } catch (android.car.CarNotConnectedException e) {
112e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            throw new CarNotConnectedException(e);
113e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        }
114e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    }
115e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park
116e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    @Override
117150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park    public void removeListener(OnSensorChangedListener listener) {
118f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv        mCarSensorsProxy.unregisterSensorListener(listener);
119d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup        OnSensorChangedListenerProxy proxy = null;
120e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        synchronized (this) {
121e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            proxy = findListenerLocked(listener);
122e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            if (proxy == null) {
123e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park                return;
124e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            }
125e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            mListeners.remove(proxy);
126e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        }
127150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park        mManager.unregisterListener(proxy);
128e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    }
129e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park
130e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    @Override
131150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park    public void removeListener(OnSensorChangedListener listener, int sensorType) {
132f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv        mCarSensorsProxy.unregisterSensorListener(listener, sensorType);
133d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup        OnSensorChangedListenerProxy proxy = null;
134e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        synchronized (this) {
135e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            proxy = findListenerLocked(listener);
136e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            if (proxy == null) {
137e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park                return;
138e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            }
139f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv            proxy.sensors.remove(sensorType);
140f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv            if (proxy.sensors.isEmpty()) {
141e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park                mListeners.remove(proxy);
142e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            }
143e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        }
144150d8de43e71a624106e90bcc04067414c42ef18Keun-young Park        mManager.unregisterListener(proxy, sensorType);
145e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    }
146e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park
147e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    @Override
148e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    public CarSensorEvent getLatestSensorEvent(int type) throws CarNotConnectedException {
149f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv        if (isSensorProxied(type)) {
150f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv            return mCarSensorsProxy.getLatestSensorEvent(type);
151f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv        }
152e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        try {
153e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            return convert(mManager.getLatestSensorEvent(type));
154e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        } catch (android.car.CarNotConnectedException e) {
155e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            throw new CarNotConnectedException(e);
156e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        }
157e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    }
158e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park
159e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    @Override
160a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4cSteve Paik    public CarSensorConfig getSensorConfig(@SensorType int type)
161a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4cSteve Paik        throws CarNotConnectedException {
162a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4cSteve Paik        try {
163a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4cSteve Paik            return convert(mManager.getSensorConfig(type));
164a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4cSteve Paik        } catch (android.car.CarNotConnectedException e) {
165a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4cSteve Paik            throw new CarNotConnectedException(e);
166a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4cSteve Paik        }
167a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4cSteve Paik    }
168a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4cSteve Paik
169a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4cSteve Paik    @Override
170e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    public void onCarDisconnected() {
171e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        //nothing to do
172e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    }
173e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park
174d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup    private OnSensorChangedListenerProxy findListenerLocked(OnSensorChangedListener listener) {
175d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup        for (OnSensorChangedListenerProxy proxy : mListeners) {
176e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            if (proxy.listener == listener) {
177e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park                return proxy;
178e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            }
179e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        }
180e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        return null;
181e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    }
182e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park
183e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    private static CarSensorEvent convert(android.car.hardware.CarSensorEvent event) {
184e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        if (event == null) {
185e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            return null;
186e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        }
187d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup        return new CarSensorEvent(event.sensorType, event.timestamp, event.floatValues,
188289ab99688d226518e47a7e47c9ffc20f221f0a6Steve Paik                event.intValues, event.longValues);
189e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    }
190e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park
191a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4cSteve Paik    private static CarSensorConfig convert(android.car.hardware.CarSensorConfig cfg) {
192a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4cSteve Paik        if (cfg == null) {
193a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4cSteve Paik            return null;
194a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4cSteve Paik        }
195a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4cSteve Paik        return new CarSensorConfig(cfg.getType(), cfg.getBundle());
196a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4cSteve Paik    }
197a2819901c1b4f56e4950dd5cb6bf6c9e8042cf4cSteve Paik
198d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup    private static class OnSensorChangedListenerProxy
199d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup            implements android.car.hardware.CarSensorManager.OnSensorChangedListener {
200e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park
201d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup        public final OnSensorChangedListener listener;
202d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup        public final Set<Integer> sensors = new HashSet<>();
203d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup        public final CarSensorManager manager;
204e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park
205d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup        OnSensorChangedListenerProxy(OnSensorChangedListener listener, int sensor,
206d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup                CarSensorManager manager) {
207e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            this.listener = listener;
208f6e2de20ae9b13b7d4a6f5bed0f28ea2c8069742Vitalii Tomkiv            this.sensors.add(sensor);
209d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup            this.manager = manager;
210e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        }
211e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park
212e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        @Override
213e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        public void onSensorChanged(android.car.hardware.CarSensorEvent event) {
214e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            CarSensorEvent newEvent = convert(event);
215d72b53500006e84b0c69e650878267c693c164a3Jason Tholstrup            listener.onSensorChanged(manager, newEvent);
216e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        }
217e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park    }
218e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park}
219