1/** 2 * Copyright (C) 2017 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 com.android.server.broadcastradio; 18 19import android.annotation.NonNull; 20import android.hardware.radio.ITuner; 21import android.hardware.radio.ITunerCallback; 22import android.hardware.radio.RadioManager; 23import android.hardware.radio.RadioMetadata; 24import android.hardware.radio.RadioTuner; 25import android.os.IBinder; 26import android.os.RemoteException; 27import android.util.Slog; 28 29class TunerCallback implements ITunerCallback { 30 private static final String TAG = "BroadcastRadioService.TunerCallback"; 31 32 /** 33 * This field is used by native code, do not access or modify. 34 */ 35 private final long mNativeContext; 36 37 @NonNull private final Tuner mTuner; 38 @NonNull private final ITunerCallback mClientCallback; 39 40 TunerCallback(@NonNull Tuner tuner, @NonNull ITunerCallback clientCallback, int halRev) { 41 mTuner = tuner; 42 mClientCallback = clientCallback; 43 mNativeContext = nativeInit(tuner, halRev); 44 } 45 46 @Override 47 protected void finalize() throws Throwable { 48 nativeFinalize(mNativeContext); 49 super.finalize(); 50 } 51 52 private native long nativeInit(@NonNull Tuner tuner, int halRev); 53 private native void nativeFinalize(long nativeContext); 54 private native void nativeDetach(long nativeContext); 55 56 public void detach() { 57 nativeDetach(mNativeContext); 58 } 59 60 private interface RunnableThrowingRemoteException { 61 void run() throws RemoteException; 62 } 63 64 private void dispatch(RunnableThrowingRemoteException func) { 65 try { 66 func.run(); 67 } catch (RemoteException e) { 68 Slog.e(TAG, "client died", e); 69 } 70 } 71 72 // called from native side 73 private void handleHwFailure() { 74 onError(RadioTuner.ERROR_HARDWARE_FAILURE); 75 mTuner.close(); 76 } 77 78 @Override 79 public void onError(int status) { 80 dispatch(() -> mClientCallback.onError(status)); 81 } 82 83 @Override 84 public void onConfigurationChanged(RadioManager.BandConfig config) { 85 dispatch(() -> mClientCallback.onConfigurationChanged(config)); 86 } 87 88 @Override 89 public void onCurrentProgramInfoChanged(RadioManager.ProgramInfo info) { 90 dispatch(() -> mClientCallback.onCurrentProgramInfoChanged(info)); 91 } 92 93 @Override 94 public void onTrafficAnnouncement(boolean active) { 95 dispatch(() -> mClientCallback.onTrafficAnnouncement(active)); 96 } 97 98 @Override 99 public void onEmergencyAnnouncement(boolean active) { 100 dispatch(() -> mClientCallback.onEmergencyAnnouncement(active)); 101 } 102 103 @Override 104 public void onAntennaState(boolean connected) { 105 dispatch(() -> mClientCallback.onAntennaState(connected)); 106 } 107 108 @Override 109 public void onBackgroundScanAvailabilityChange(boolean isAvailable) { 110 dispatch(() -> mClientCallback.onBackgroundScanAvailabilityChange(isAvailable)); 111 } 112 113 @Override 114 public void onBackgroundScanComplete() { 115 dispatch(() -> mClientCallback.onBackgroundScanComplete()); 116 } 117 118 @Override 119 public void onProgramListChanged() { 120 dispatch(() -> mClientCallback.onProgramListChanged()); 121 } 122 123 @Override 124 public IBinder asBinder() { 125 throw new RuntimeException("Not a binder"); 126 } 127} 128