1347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk/** 2347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk * Copyright (C) 2017 The Android Open Source Project 3347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk * 4347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk * Licensed under the Apache License, Version 2.0 (the "License"); 5347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk * you may not use this file except in compliance with the License. 6347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk * You may obtain a copy of the License at 7347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk * 8347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk * http://www.apache.org/licenses/LICENSE-2.0 9347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk * 10347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk * Unless required by applicable law or agreed to in writing, software 11347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk * distributed under the License is distributed on an "AS IS" BASIS, 12347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk * See the License for the specific language governing permissions and 14347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk * limitations under the License. 15347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk */ 16347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 17347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczykpackage android.hardware.radio; 18347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 19347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczykimport android.annotation.NonNull; 20347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczykimport android.annotation.Nullable; 214482b1413656b9c0c5937b4d7a73235f872a6678Tomasz Wasilczykimport android.graphics.Bitmap; 22347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczykimport android.os.RemoteException; 23347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczykimport android.util.Log; 24347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 25347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczykimport java.util.List; 260f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczykimport java.util.Map; 278e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczykimport java.util.Objects; 28347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 29347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk/** 30347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk * Implements the RadioTuner interface by forwarding calls to radio service. 31347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk */ 32347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczykclass TunerAdapter extends RadioTuner { 336b4b646d9c0fa42973a429dbe78c8919a2772961Tomasz Wasilczyk private static final String TAG = "BroadcastRadio.TunerAdapter"; 34347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 35347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk @NonNull private final ITuner mTuner; 36436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk @NonNull private final TunerCallbackAdapter mCallback; 37d7c21d3cbfe8e1016a92234f89d6fe8c110144d1Tomasz Wasilczyk private boolean mIsClosed = false; 38347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 398cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk private @RadioManager.Band int mBand; 408cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk 41436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk private ProgramList mLegacyListProxy; 42436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk private Map<String, String> mLegacyListFilter; 43436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk 44436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk TunerAdapter(@NonNull ITuner tuner, @NonNull TunerCallbackAdapter callback, 45436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk @RadioManager.Band int band) { 46436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk mTuner = Objects.requireNonNull(tuner); 47436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk mCallback = Objects.requireNonNull(callback); 488cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk mBand = band; 49347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 50347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 51347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk @Override 52347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk public void close() { 53d7c21d3cbfe8e1016a92234f89d6fe8c110144d1Tomasz Wasilczyk synchronized (mTuner) { 54d7c21d3cbfe8e1016a92234f89d6fe8c110144d1Tomasz Wasilczyk if (mIsClosed) { 5514752375d74908632195a875f32a2b5fd1e719efTomasz Wasilczyk Log.v(TAG, "Tuner is already closed"); 56d7c21d3cbfe8e1016a92234f89d6fe8c110144d1Tomasz Wasilczyk return; 57d7c21d3cbfe8e1016a92234f89d6fe8c110144d1Tomasz Wasilczyk } 58d7c21d3cbfe8e1016a92234f89d6fe8c110144d1Tomasz Wasilczyk mIsClosed = true; 59436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk if (mLegacyListProxy != null) { 60436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk mLegacyListProxy.close(); 61436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk mLegacyListProxy = null; 62436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk } 63d0c78f9f28599ac97dbca06c1634238f9b25be40Tomasz Wasilczyk mCallback.close(); 64d7c21d3cbfe8e1016a92234f89d6fe8c110144d1Tomasz Wasilczyk } 65d7c21d3cbfe8e1016a92234f89d6fe8c110144d1Tomasz Wasilczyk try { 66d7c21d3cbfe8e1016a92234f89d6fe8c110144d1Tomasz Wasilczyk mTuner.close(); 67d7c21d3cbfe8e1016a92234f89d6fe8c110144d1Tomasz Wasilczyk } catch (RemoteException e) { 68d7c21d3cbfe8e1016a92234f89d6fe8c110144d1Tomasz Wasilczyk Log.e(TAG, "Exception trying to close tuner", e); 69d7c21d3cbfe8e1016a92234f89d6fe8c110144d1Tomasz Wasilczyk } 70347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 71347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 72347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk @Override 73347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk public int setConfiguration(RadioManager.BandConfig config) { 74ca98cde254fef6c31634d8a3069a0d7b76ecf908Tomasz Wasilczyk if (config == null) return RadioManager.STATUS_BAD_VALUE; 758b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk try { 768b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk mTuner.setConfiguration(config); 778cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk mBand = config.getType(); 788b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk return RadioManager.STATUS_OK; 798b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk } catch (IllegalArgumentException e) { 808b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk Log.e(TAG, "Can't set configuration", e); 818b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk return RadioManager.STATUS_BAD_VALUE; 828b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk } catch (RemoteException e) { 839fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk Log.e(TAG, "service died", e); 849fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk return RadioManager.STATUS_DEAD_OBJECT; 858b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk } 86347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 87347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 88347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk @Override 89347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk public int getConfiguration(RadioManager.BandConfig[] config) { 908b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk if (config == null || config.length != 1) { 918b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk throw new IllegalArgumentException("The argument must be an array of length 1"); 928b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk } 938b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk try { 948b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk config[0] = mTuner.getConfiguration(); 958b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk return RadioManager.STATUS_OK; 968b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk } catch (RemoteException e) { 979fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk Log.e(TAG, "service died", e); 989fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk return RadioManager.STATUS_DEAD_OBJECT; 998b6db4f2eb02f231dd8006debbc1e1be1181178aTomasz Wasilczyk } 100347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 101347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 102347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk @Override 103347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk public int setMute(boolean mute) { 1049fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk try { 1059fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk mTuner.setMuted(mute); 1069fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk } catch (IllegalStateException e) { 1079fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk Log.e(TAG, "Can't set muted", e); 1089fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk return RadioManager.STATUS_ERROR; 1099fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk } catch (RemoteException e) { 1109fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk Log.e(TAG, "service died", e); 1119fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk return RadioManager.STATUS_DEAD_OBJECT; 1129fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk } 1139fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk return RadioManager.STATUS_OK; 114347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 115347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 116347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk @Override 117347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk public boolean getMute() { 1189fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk try { 1199fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk return mTuner.isMuted(); 1209fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk } catch (RemoteException e) { 1219fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk Log.e(TAG, "service died", e); 1229fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk return true; 1239fa0287c1802df074d4039489dcfad712c19bcbaTomasz Wasilczyk } 124347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 125347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 126347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk @Override 127347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk public int step(int direction, boolean skipSubChannel) { 1282383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk try { 1292383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk mTuner.step(direction == RadioTuner.DIRECTION_DOWN, skipSubChannel); 1302383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk } catch (IllegalStateException e) { 1312383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk Log.e(TAG, "Can't step", e); 1322383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk return RadioManager.STATUS_INVALID_OPERATION; 1332383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk } catch (RemoteException e) { 1342383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk Log.e(TAG, "service died", e); 1352383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk return RadioManager.STATUS_DEAD_OBJECT; 1362383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk } 1372383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk return RadioManager.STATUS_OK; 138347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 139347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 140347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk @Override 141347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk public int scan(int direction, boolean skipSubChannel) { 1422383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk try { 1432383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk mTuner.scan(direction == RadioTuner.DIRECTION_DOWN, skipSubChannel); 1442383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk } catch (IllegalStateException e) { 1452383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk Log.e(TAG, "Can't scan", e); 1462383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk return RadioManager.STATUS_INVALID_OPERATION; 1472383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk } catch (RemoteException e) { 1482383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk Log.e(TAG, "service died", e); 1492383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk return RadioManager.STATUS_DEAD_OBJECT; 1502383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk } 1512383793eaee223546985ee12c2f35a3445e34b1cTomasz Wasilczyk return RadioManager.STATUS_OK; 152347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 153347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 154347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk @Override 155347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk public int tune(int channel, int subChannel) { 15637d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk try { 1578cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk mTuner.tune(ProgramSelector.createAmFmSelector(mBand, channel, subChannel)); 15837d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk } catch (IllegalStateException e) { 15937d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk Log.e(TAG, "Can't tune", e); 16037d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk return RadioManager.STATUS_INVALID_OPERATION; 16137d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk } catch (IllegalArgumentException e) { 16237d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk Log.e(TAG, "Can't tune", e); 16337d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk return RadioManager.STATUS_BAD_VALUE; 16437d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk } catch (RemoteException e) { 16537d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk Log.e(TAG, "service died", e); 16637d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk return RadioManager.STATUS_DEAD_OBJECT; 16737d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk } 16837d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk return RadioManager.STATUS_OK; 169347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 170347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 171347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk @Override 1728cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk public void tune(@NonNull ProgramSelector selector) { 1738cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk try { 1748cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk mTuner.tune(selector); 1758cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk } catch (RemoteException e) { 1768cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk throw new RuntimeException("service died", e); 1778cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk } 1788cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk } 1798cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk 1808cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk @Override 181347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk public int cancel() { 18237d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk try { 18337d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk mTuner.cancel(); 18437d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk } catch (IllegalStateException e) { 18537d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk Log.e(TAG, "Can't cancel", e); 18637d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk return RadioManager.STATUS_INVALID_OPERATION; 18737d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk } catch (RemoteException e) { 18837d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk Log.e(TAG, "service died", e); 18937d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk return RadioManager.STATUS_DEAD_OBJECT; 19037d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk } 19137d986d17d0210706be907ce9119b711eeaca235Tomasz Wasilczyk return RadioManager.STATUS_OK; 192347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 193347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 194347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk @Override 195c4cd823a2e4ce62d3a1c6ee6c71bb406c564608cTomasz Wasilczyk public void cancelAnnouncement() { 196c4cd823a2e4ce62d3a1c6ee6c71bb406c564608cTomasz Wasilczyk try { 197c4cd823a2e4ce62d3a1c6ee6c71bb406c564608cTomasz Wasilczyk mTuner.cancelAnnouncement(); 198c4cd823a2e4ce62d3a1c6ee6c71bb406c564608cTomasz Wasilczyk } catch (RemoteException e) { 199c4cd823a2e4ce62d3a1c6ee6c71bb406c564608cTomasz Wasilczyk throw new RuntimeException("service died", e); 200c4cd823a2e4ce62d3a1c6ee6c71bb406c564608cTomasz Wasilczyk } 201c4cd823a2e4ce62d3a1c6ee6c71bb406c564608cTomasz Wasilczyk } 202c4cd823a2e4ce62d3a1c6ee6c71bb406c564608cTomasz Wasilczyk 203c4cd823a2e4ce62d3a1c6ee6c71bb406c564608cTomasz Wasilczyk @Override 204347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk public int getProgramInformation(RadioManager.ProgramInfo[] info) { 205347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk if (info == null || info.length != 1) { 2063b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk Log.e(TAG, "The argument must be an array of length 1"); 2073b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk return RadioManager.STATUS_BAD_VALUE; 208347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 2093b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk 2103b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk RadioManager.ProgramInfo current = mCallback.getCurrentProgramInformation(); 2113b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk if (current == null) { 2123b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk Log.w(TAG, "Didn't get program info yet"); 2133b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk return RadioManager.STATUS_INVALID_OPERATION; 214347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 2153b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk info[0] = current; 2163b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk return RadioManager.STATUS_OK; 217347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 218347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 219347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk @Override 2204482b1413656b9c0c5937b4d7a73235f872a6678Tomasz Wasilczyk public @Nullable Bitmap getMetadataImage(int id) { 2214482b1413656b9c0c5937b4d7a73235f872a6678Tomasz Wasilczyk try { 2224482b1413656b9c0c5937b4d7a73235f872a6678Tomasz Wasilczyk return mTuner.getImage(id); 2234482b1413656b9c0c5937b4d7a73235f872a6678Tomasz Wasilczyk } catch (RemoteException e) { 2244482b1413656b9c0c5937b4d7a73235f872a6678Tomasz Wasilczyk throw new RuntimeException("service died", e); 2254482b1413656b9c0c5937b4d7a73235f872a6678Tomasz Wasilczyk } 2264482b1413656b9c0c5937b4d7a73235f872a6678Tomasz Wasilczyk } 2274482b1413656b9c0c5937b4d7a73235f872a6678Tomasz Wasilczyk 2284482b1413656b9c0c5937b4d7a73235f872a6678Tomasz Wasilczyk @Override 229347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk public boolean startBackgroundScan() { 230d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk try { 231d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk return mTuner.startBackgroundScan(); 232d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk } catch (RemoteException e) { 233d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk throw new RuntimeException("service died", e); 234d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk } 235347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 236347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 237347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk @Override 2380f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk public @NonNull List<RadioManager.ProgramInfo> 2390f1776d08b43f5f71a9f89b6a4f1838df4d3d744Tomasz Wasilczyk getProgramList(@Nullable Map<String, String> vendorFilter) { 240436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk synchronized (mTuner) { 241436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk if (mLegacyListProxy == null || !Objects.equals(mLegacyListFilter, vendorFilter)) { 242436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk Log.i(TAG, "Program list filter has changed, requesting new list"); 243436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk mLegacyListProxy = new ProgramList(); 244436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk mLegacyListFilter = vendorFilter; 245436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk 246436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk mCallback.clearLastCompleteList(); 247436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk mCallback.setProgramListObserver(mLegacyListProxy, () -> { }); 248436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk try { 249436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk mTuner.startProgramListUpdates(new ProgramList.Filter(vendorFilter)); 250436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk } catch (RemoteException ex) { 251436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk throw new RuntimeException("service died", ex); 252436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk } 253436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk } 254436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk 255436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk List<RadioManager.ProgramInfo> list = mCallback.getLastCompleteList(); 256436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk if (list == null) throw new IllegalStateException("Program list is not ready yet"); 257436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk return list; 258436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk } 259436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk } 260436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk 261436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk @Override 262436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk public @Nullable ProgramList getDynamicProgramList(@Nullable ProgramList.Filter filter) { 263436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk synchronized (mTuner) { 264436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk if (mLegacyListProxy != null) { 265436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk mLegacyListProxy.close(); 266436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk mLegacyListProxy = null; 267436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk } 268436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk mLegacyListFilter = null; 269436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk 270436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk ProgramList list = new ProgramList(); 271436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk mCallback.setProgramListObserver(list, () -> { 272436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk try { 273436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk mTuner.stopProgramListUpdates(); 274436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk } catch (RemoteException ex) { 275436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk Log.e(TAG, "Couldn't stop program list updates", ex); 276436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk } 277436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk }); 278436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk 279436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk try { 280436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk mTuner.startProgramListUpdates(filter); 281436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk } catch (UnsupportedOperationException ex) { 282d0c78f9f28599ac97dbca06c1634238f9b25be40Tomasz Wasilczyk Log.i(TAG, "Program list is not supported with this hardware"); 283436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk return null; 284436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk } catch (RemoteException ex) { 285436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk mCallback.setProgramListObserver(null, () -> { }); 286436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk throw new RuntimeException("service died", ex); 287436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk } 288436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk 289436128f23ae4efc52bbfa3cdde666a139b4bedc4Tomasz Wasilczyk return list; 290d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk } 291347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 292347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 293347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk @Override 294347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk public boolean isAnalogForced() { 2953b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk try { 2963b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk return isConfigFlagSet(RadioManager.CONFIG_FORCE_ANALOG); 2973b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk } catch (UnsupportedOperationException ex) { 2983b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk throw new IllegalStateException(ex); 2993b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk } 300ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk } 301ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk 302ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk @Override 303ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk public void setAnalogForced(boolean isForced) { 3043b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk try { 3053b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk setConfigFlag(RadioManager.CONFIG_FORCE_ANALOG, isForced); 3063b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk } catch (UnsupportedOperationException ex) { 3073b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk throw new IllegalStateException(ex); 3083b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk } 309ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk } 310ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk 311ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk @Override 312ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk public boolean isConfigFlagSupported(@RadioManager.ConfigFlag int flag) { 313d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk try { 314ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk return mTuner.isConfigFlagSupported(flag); 315d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk } catch (RemoteException e) { 316d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk throw new RuntimeException("service died", e); 317d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk } 318347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 319347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 320347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk @Override 321ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk public boolean isConfigFlagSet(@RadioManager.ConfigFlag int flag) { 322ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk try { 323ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk return mTuner.isConfigFlagSet(flag); 324ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk } catch (RemoteException e) { 325ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk throw new RuntimeException("service died", e); 326ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk } 327ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk } 328ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk 329ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk @Override 330ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk public void setConfigFlag(@RadioManager.ConfigFlag int flag, boolean value) { 331d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk try { 332ce40fe9b1b15221eb91d8b82322b695161664932Tomasz Wasilczyk mTuner.setConfigFlag(flag, value); 333d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk } catch (RemoteException e) { 334d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk throw new RuntimeException("service died", e); 335d3d53f669268fe8dd15f16abbd0504f7b9e38405Tomasz Wasilczyk } 336347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 337347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 338347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk @Override 3398e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk public @NonNull Map<String, String> setParameters(@NonNull Map<String, String> parameters) { 3408e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk try { 3418e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk return mTuner.setParameters(Objects.requireNonNull(parameters)); 3428e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk } catch (RemoteException e) { 3438e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk throw new RuntimeException("service died", e); 3448e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk } 3458e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk } 3468e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk 3478e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk @Override 3488e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk public @NonNull Map<String, String> getParameters(@NonNull List<String> keys) { 3498e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk try { 3508e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk return mTuner.getParameters(Objects.requireNonNull(keys)); 3518e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk } catch (RemoteException e) { 3528e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk throw new RuntimeException("service died", e); 3538e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk } 3548e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk } 3558e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk 3568e932c61db78e7a04f6a98e070089f10abdccf1aTomasz Wasilczyk @Override 357347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk public boolean isAntennaConnected() { 3583b4465e65688f899f2eecf5701cda044a3104523Tomasz Wasilczyk return mCallback.isAntennaConnected(); 359347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 360347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk 361347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk @Override 362347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk public boolean hasControl() { 363468a53b71025a42dde24922e0255ab3251e63fbeTomasz Wasilczyk try { 364468a53b71025a42dde24922e0255ab3251e63fbeTomasz Wasilczyk // don't rely on mIsClosed, as tuner might get closed internally 365468a53b71025a42dde24922e0255ab3251e63fbeTomasz Wasilczyk return !mTuner.isClosed(); 366468a53b71025a42dde24922e0255ab3251e63fbeTomasz Wasilczyk } catch (RemoteException e) { 367468a53b71025a42dde24922e0255ab3251e63fbeTomasz Wasilczyk return false; 368468a53b71025a42dde24922e0255ab3251e63fbeTomasz Wasilczyk } 369347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk } 370347192e0da1f39347e7ab7b58b002f166b4afaa7Tomasz Wasilczyk} 371