13cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal/*
23cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * Copyright (C) 2015 The Android Open Source Project
33cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal *
43cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * Licensed under the Apache License, Version 2.0 (the "License");
53cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * you may not use this file except in compliance with the License.
63cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * You may obtain a copy of the License at
73cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal *
83cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal *      http://www.apache.org/licenses/LICENSE-2.0
93cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal *
103cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * Unless required by applicable law or agreed to in writing, software
113cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * distributed under the License is distributed on an "AS IS" BASIS,
123cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * See the License for the specific language governing permissions and
143cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * limitations under the License.
153cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal */
163cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
17e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkpackage android.car.hardware.radio;
183cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
193cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwalimport android.annotation.SystemApi;
20e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport android.car.Car;
21e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport android.car.CarManagerBase;
22e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport android.car.CarNotConnectedException;
233cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwalimport android.hardware.radio.RadioManager;
243cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwalimport android.os.Handler;
25e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport android.os.IBinder;
263cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwalimport android.os.Looper;
273cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwalimport android.os.Message;
283cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwalimport android.os.RemoteException;
293cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwalimport android.util.Log;
303cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
313cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwalimport com.android.internal.annotations.GuardedBy;
323cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
333cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwalimport java.lang.ref.WeakReference;
343cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
353cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal/**
363cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * Car Radio manager.
373cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal *
383cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * This API works in conjunction with the {@link RadioManager.java} and provides
393cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * features additional to the ones provided in there. It supports:
403cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal *
413cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * 1. Capability to control presets.
42280b5721254e5ac974404e02e7589f17f560d1f9Vitalii Tomkiv * @hide
433cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal */
443cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal@SystemApi
453cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwalpublic class CarRadioManager implements CarManagerBase {
463cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    public final static boolean DBG = true;
47bbe5f27f95e7aaa6363a184905af94017596d73aJoe Onorato    public final static String TAG = "CarRadioManager";
483cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
493cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    // Constants handled in the handler (see mHandler below).
503cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    private final static int MSG_RADIO_EVENT = 0;
513cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
523cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    private int mCount = 0;
533cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    private final ICarRadio mService;
543cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    @GuardedBy("this")
553cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    private CarRadioEventListener mListener = null;
563cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    @GuardedBy("this")
573cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    private CarRadioEventListenerToService mListenerToService = null;
583cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    private static final class EventCallbackHandler extends Handler {
593cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        WeakReference<CarRadioManager> mMgr;
603cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
613cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        EventCallbackHandler(CarRadioManager mgr, Looper looper) {
623cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            super(looper);
633cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            mMgr = new WeakReference<CarRadioManager>(mgr);
643cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        }
653cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
663cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        @Override
673cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        public void handleMessage(Message msg) {
683cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            switch (msg.what) {
693cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal                case MSG_RADIO_EVENT:
703cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal                    CarRadioManager mgr = mMgr.get();
713cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal                    if (mgr != null) {
723cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal                        mgr.dispatchEventToClient((CarRadioEvent) msg.obj);
733cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal                    }
743cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal                    break;
753cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal                default:
763cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal                    Log.e(TAG, "Event type not handled?" + msg);
773cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            }
783cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        }
793cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    }
803cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
813cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    private final Handler mHandler;
823cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
833cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    private static class CarRadioEventListenerToService extends ICarRadioEventListener.Stub {
843cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        private final WeakReference<CarRadioManager> mManager;
853cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
863cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        public CarRadioEventListenerToService(CarRadioManager manager) {
873cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            mManager = new WeakReference<CarRadioManager>(manager);
883cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        }
893cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
903cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        @Override
913cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        public void onEvent(CarRadioEvent event) {
923cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            CarRadioManager manager = mManager.get();
933cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            if (manager != null) {
943cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal                manager.handleEvent(event);
953cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            }
963cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        }
973cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    }
983cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
993cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
1003cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    /** Listener for car radio events.
1013cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     */
1023cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    public interface CarRadioEventListener {
1033cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        /**
1043cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal         * Called when there is a preset value is reprogrammed.
1053cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal         */
1063cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        void onEvent(final CarRadioEvent event);
1073cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    }
1083cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
1093cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    /**
1103cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     * Get an instance of the CarRadioManager.
1113cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     *
1123cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     * Should not be obtained directly by clients, use {@link Car.getCarManager()} instead.
1133cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     * @hide
1143cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     */
115235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv    public CarRadioManager(IBinder service, Looper looper) throws CarNotConnectedException {
116e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park        mService = ICarRadio.Stub.asInterface(service);
1173cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        mHandler = new EventCallbackHandler(this, looper);
1183cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
1193cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        // Populate the fixed values.
1203cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        try {
121e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            mCount = mService.getPresetCount();
1223cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        } catch (RemoteException ex) {
1233cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            Log.e(TAG, "Could not connect: " + ex.toString());
124235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv            throw new CarNotConnectedException(ex);
1253cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        }
1263cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    }
1273cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
1283cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    /**
1293cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     * Register {@link CarRadioEventListener} to get radio unit changes.
1303cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     */
1313cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    public synchronized void registerListener(CarRadioEventListener listener)
1323cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            throws CarNotConnectedException {
1333cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        if (mListener != null) {
134e423804f896d2374d3427c861295961bcbf50620Pavel Maltsev            throw new IllegalStateException("Listener already registered. Did you call " +
1353cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal                "registerListener() twice?");
1363cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        }
1373cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
1383cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        mListener = listener;
1393cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        try {
1403cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            mListenerToService = new CarRadioEventListenerToService(this);
141e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Park            mService.registerListener(mListenerToService);
1423cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        } catch (RemoteException ex) {
1433cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            // Do nothing.
1443cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            Log.e(TAG, "Could not connect: " + ex.toString());
1453cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            throw new CarNotConnectedException(ex);
1463cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        } catch (IllegalStateException ex) {
1473cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            Car.checkCarNotConnectedExceptionFromCarService(ex);
1483cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        }
1493cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    }
1503cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
1513cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    /**
1523cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     * Unregister {@link CarRadioEventListener}.
1533cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     */
154235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv    public synchronized void unregisterListener() throws CarNotConnectedException {
1553cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        if (DBG) {
156e423804f896d2374d3427c861295961bcbf50620Pavel Maltsev            Log.d(TAG, "unregisterListener");
1573cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        }
1583cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        try {
1593cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            mService.unregisterListener(mListenerToService);
1603cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        } catch (RemoteException ex) {
1613cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            Log.e(TAG, "Could not connect: " + ex.toString());
162235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv            throw new CarNotConnectedException(ex);
1633cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        }
1643cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        mListenerToService = null;
1653cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        mListener = null;
1663cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    }
1673cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
1683cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    /**
1693cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     * Get the number of (hard) presets supported by car radio unit.
1703cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     *
1713cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     * @return: A positive value if the call succeeded, -1 if it failed.
1723cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     */
1733cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    public int getPresetCount() {
1743cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        return mCount;
1753cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    }
1763cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
1773cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    /**
1783cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     * Get preset value for a specific radio preset.
1793cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     * @return: a {@link CarRadioPreset} object, {@link null} if the call failed.
1803cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     */
181235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv    public CarRadioPreset getPreset(int presetNumber) throws CarNotConnectedException {
1823cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        if (DBG) {
1833cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            Log.d(TAG, "getPreset");
1843cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        }
1853cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        try {
1863cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            CarRadioPreset preset = mService.getPreset(presetNumber);
1873cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            return preset;
1883cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        } catch (RemoteException ex) {
1893cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            Log.e(TAG, "getPreset failed with " + ex.toString());
190235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv            throw new CarNotConnectedException(ex);
1913cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        }
1923cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    }
1933cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
1943cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    /**
1953cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     * Set the preset value to a specific radio preset.
1963cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     *
197e423804f896d2374d3427c861295961bcbf50620Pavel Maltsev     * In order to ensure that the preset value indeed get updated, wait for event on the listener
198e423804f896d2374d3427c861295961bcbf50620Pavel Maltsev     * registered via registerListener().
1993cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     *
2003cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     * @return: {@link boolean} value which returns true if the request succeeded and false
2013cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     * otherwise. Common reasons for the failure could be:
2023cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     * a) Preset is invalid (the preset number is out of range from {@link getPresetCount()}.
2033cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     * b) Listener is not set correctly, since otherwise the user of this API cannot confirm if the
2043cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     * request succeeded.
2053cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal     */
206235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv    public boolean setPreset(CarRadioPreset preset) throws IllegalArgumentException,
207235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv            CarNotConnectedException {
2083cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        try {
209e423804f896d2374d3427c861295961bcbf50620Pavel Maltsev            return mService.setPreset(preset);
2103cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        } catch (RemoteException ex) {
211235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv            throw new CarNotConnectedException(ex);
212235f8acd3cf83079ecd0f3e1b8368b0c9886de82Vitalii Tomkiv         }
2133cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    }
2143cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
2153cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    private void dispatchEventToClient(CarRadioEvent event) {
216e423804f896d2374d3427c861295961bcbf50620Pavel Maltsev        CarRadioEventListener listener;
2173cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        synchronized (this) {
2183cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            listener = mListener;
2193cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        }
2203cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        if (listener != null) {
2213cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            listener.onEvent(event);
2223cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        } else {
2233cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal            Log.e(TAG, "Listener died, not dispatching event.");
2243cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        }
2253cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    }
2263cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
2273cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    private void handleEvent(CarRadioEvent event) {
2283cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        mHandler.sendMessage(mHandler.obtainMessage(MSG_RADIO_EVENT, event));
2293cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    }
2303cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal
2313cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    /** @hide */
2323cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    @Override
2333cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    public synchronized void onCarDisconnected() {
2343cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        mListener = null;
2353cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal        mListenerToService = null;
2363cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal    }
2373cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal}
238