1 /** 2 * Copyright (C) 2022 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 17 package com.android.server.broadcastradio; 18 19 import android.Manifest; 20 import android.content.pm.PackageManager; 21 import android.hardware.broadcastradio.IBroadcastRadio; 22 import android.hardware.radio.IAnnouncementListener; 23 import android.hardware.radio.ICloseHandle; 24 import android.hardware.radio.IRadioService; 25 import android.hardware.radio.ITuner; 26 import android.hardware.radio.ITunerCallback; 27 import android.hardware.radio.RadioManager; 28 import android.os.Binder; 29 import android.os.IBinder; 30 import android.os.RemoteException; 31 import android.os.ServiceManager; 32 import android.util.IndentingPrintWriter; 33 import android.util.Log; 34 35 import com.android.internal.annotations.VisibleForTesting; 36 import com.android.server.broadcastradio.aidl.BroadcastRadioServiceImpl; 37 import com.android.server.utils.Slogf; 38 39 import java.io.FileDescriptor; 40 import java.io.PrintWriter; 41 import java.util.ArrayList; 42 import java.util.Arrays; 43 import java.util.List; 44 import java.util.Objects; 45 46 /** 47 * Wrapper for AIDL interface for BroadcastRadio HAL 48 */ 49 final class IRadioServiceAidlImpl extends IRadioService.Stub { 50 private static final String TAG = "BcRadioSrvAidl"; 51 52 private static final List<String> SERVICE_NAMES = Arrays.asList( 53 IBroadcastRadio.DESCRIPTOR + "/amfm", IBroadcastRadio.DESCRIPTOR + "/dab"); 54 55 private final BroadcastRadioServiceImpl mAidlHalClient; 56 private final BroadcastRadioService mService; 57 58 /** 59 * Gets names of all AIDL BroadcastRadio HAL services available. 60 */ getServicesNames()61 public static ArrayList<String> getServicesNames() { 62 ArrayList<String> serviceList = new ArrayList<>(); 63 for (int i = 0; i < SERVICE_NAMES.size(); i++) { 64 IBinder serviceBinder = ServiceManager.waitForDeclaredService(SERVICE_NAMES.get(i)); 65 if (serviceBinder != null) { 66 serviceList.add(SERVICE_NAMES.get(i)); 67 } 68 } 69 return serviceList; 70 } 71 IRadioServiceAidlImpl(BroadcastRadioService service, List<String> serviceList, RadioServiceUserController userController)72 IRadioServiceAidlImpl(BroadcastRadioService service, List<String> serviceList, 73 RadioServiceUserController userController) { 74 this(service, new BroadcastRadioServiceImpl(serviceList, userController)); 75 Slogf.i(TAG, "Initialize BroadcastRadioServiceAidl(%s)", service); 76 } 77 78 @VisibleForTesting IRadioServiceAidlImpl(BroadcastRadioService service, BroadcastRadioServiceImpl halAidl)79 IRadioServiceAidlImpl(BroadcastRadioService service, BroadcastRadioServiceImpl halAidl) { 80 mService = Objects.requireNonNull(service, "Broadcast radio service cannot be null"); 81 mAidlHalClient = Objects.requireNonNull(halAidl, 82 "Broadcast radio service implementation for AIDL HAL cannot be null"); 83 } 84 85 @Override listModules()86 public List<RadioManager.ModuleProperties> listModules() { 87 mService.enforcePolicyAccess(); 88 return mAidlHalClient.listModules(); 89 } 90 91 @Override openTuner(int moduleId, RadioManager.BandConfig bandConfig, boolean withAudio, ITunerCallback callback)92 public ITuner openTuner(int moduleId, RadioManager.BandConfig bandConfig, 93 boolean withAudio, ITunerCallback callback) throws RemoteException { 94 if (isDebugEnabled()) { 95 Slogf.d(TAG, "Opening module %d", moduleId); 96 } 97 mService.enforcePolicyAccess(); 98 if (callback == null) { 99 throw new IllegalArgumentException("Callback must not be null"); 100 } 101 return mAidlHalClient.openSession(moduleId, bandConfig, withAudio, callback); 102 } 103 104 @Override addAnnouncementListener(int[] enabledTypes, IAnnouncementListener listener)105 public ICloseHandle addAnnouncementListener(int[] enabledTypes, 106 IAnnouncementListener listener) { 107 if (isDebugEnabled()) { 108 Slogf.d(TAG, "Adding announcement listener for %s", Arrays.toString(enabledTypes)); 109 } 110 Objects.requireNonNull(enabledTypes, "Enabled announcement types cannot be null"); 111 Objects.requireNonNull(listener, "Announcement listener cannot be null"); 112 mService.enforcePolicyAccess(); 113 114 return mAidlHalClient.addAnnouncementListener(enabledTypes, listener); 115 } 116 117 @Override dump(FileDescriptor fd, PrintWriter printWriter, String[] args)118 protected void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { 119 if (mService.getContext().checkCallingOrSelfPermission(Manifest.permission.DUMP) 120 != PackageManager.PERMISSION_GRANTED) { 121 printWriter.println("Permission Denial: can't dump AIDL BroadcastRadioService from " 122 + "from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 123 + " without permission " + Manifest.permission.DUMP); 124 return; 125 } 126 IndentingPrintWriter radioPrintWriter = new IndentingPrintWriter(printWriter); 127 radioPrintWriter.printf("BroadcastRadioService\n"); 128 129 radioPrintWriter.increaseIndent(); 130 radioPrintWriter.printf("AIDL HAL client:\n"); 131 132 radioPrintWriter.increaseIndent(); 133 mAidlHalClient.dumpInfo(radioPrintWriter); 134 radioPrintWriter.decreaseIndent(); 135 136 radioPrintWriter.decreaseIndent(); 137 } 138 isDebugEnabled()139 private static boolean isDebugEnabled() { 140 return Log.isLoggable(TAG, Log.DEBUG); 141 } 142 } 143