blob: 54a4ad42fd99e76930c508872fcfb1166ea41f05 [file] [log] [blame]
Tomasz Wasilczyk347192e2017-04-04 11:13:44 -07001/**
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
Tomasz Wasilczyk6b4b6462017-07-19 10:52:28 -070017package com.android.server.broadcastradio;
Tomasz Wasilczyk347192e2017-04-04 11:13:44 -070018
Tomasz Wasilczyk32d26a32017-06-14 13:54:03 -070019import android.Manifest;
Tomasz Wasilczyk347192e2017-04-04 11:13:44 -070020import android.content.Context;
Tomasz Wasilczyk32d26a32017-06-14 13:54:03 -070021import android.content.pm.PackageManager;
Tomasz Wasilczykf151a7b2018-01-11 16:03:46 -080022import android.hardware.radio.IAnnouncementListener;
23import android.hardware.radio.ICloseHandle;
Tomasz Wasilczyk347192e2017-04-04 11:13:44 -070024import android.hardware.radio.IRadioService;
25import android.hardware.radio.ITuner;
Tomasz Wasilczyk21348172017-04-20 14:02:42 -070026import android.hardware.radio.ITunerCallback;
Tomasz Wasilczyk347192e2017-04-04 11:13:44 -070027import android.hardware.radio.RadioManager;
Tomasz Wasilczyk436128f2018-01-08 16:46:09 -080028import android.os.RemoteException;
Tomasz Wasilczykf58305d2017-12-28 14:03:15 -080029import android.util.Slog;
Tomasz Wasilczyk347192e2017-04-04 11:13:44 -070030
31import com.android.server.SystemService;
Tomasz Wasilczykf151a7b2018-01-11 16:03:46 -080032import com.android.server.broadcastradio.hal2.AnnouncementAggregator;
Tomasz Wasilczyk347192e2017-04-04 11:13:44 -070033
George Lu5af724322019-03-13 17:11:21 -070034import java.util.ArrayList;
Tomasz Wasilczykf151a7b2018-01-11 16:03:46 -080035import java.util.Arrays;
Tomasz Wasilczykd15c9df2017-06-13 10:10:36 -070036import java.util.List;
Tomasz Wasilczykd65b3ca2017-12-13 08:26:25 -080037import java.util.Objects;
38import java.util.OptionalInt;
Tomasz Wasilczykd15c9df2017-06-13 10:10:36 -070039
Tomasz Wasilczyk6b4b6462017-07-19 10:52:28 -070040public class BroadcastRadioService extends SystemService {
Tomasz Wasilczykf58305d2017-12-28 14:03:15 -080041 private static final String TAG = "BcRadioSrv";
Tomasz Wasilczykf151a7b2018-01-11 16:03:46 -080042 private static final boolean DEBUG = false;
Tomasz Wasilczykf58305d2017-12-28 14:03:15 -080043
Tomasz Wasilczyk6b4b6462017-07-19 10:52:28 -070044 private final ServiceImpl mServiceImpl = new ServiceImpl();
Tomasz Wasilczykd7c21d32017-04-17 17:02:06 -070045
George Lu5af724322019-03-13 17:11:21 -070046 private final com.android.server.broadcastradio.hal1.BroadcastRadioService mHal1;
47 private final com.android.server.broadcastradio.hal2.BroadcastRadioService mHal2;
Tomasz Wasilczykd65b3ca2017-12-13 08:26:25 -080048
Tomasz Wasilczykf13b8412017-05-09 11:54:35 -070049 private final Object mLock = new Object();
George Lu5af724322019-03-13 17:11:21 -070050 private List<RadioManager.ModuleProperties> mV1Modules = null;
Tomasz Wasilczykf13b8412017-05-09 11:54:35 -070051
Tomasz Wasilczyk6b4b6462017-07-19 10:52:28 -070052 public BroadcastRadioService(Context context) {
Tomasz Wasilczyk347192e2017-04-04 11:13:44 -070053 super(context);
George Lu5af724322019-03-13 17:11:21 -070054
55 mHal1 = new com.android.server.broadcastradio.hal1.BroadcastRadioService();
56 mV1Modules = mHal1.loadModules();
57 OptionalInt max = mV1Modules.stream().mapToInt(RadioManager.ModuleProperties::getId).max();
58 mHal2 = new com.android.server.broadcastradio.hal2.BroadcastRadioService(
59 max.isPresent() ? max.getAsInt() + 1 : 0);
Tomasz Wasilczyk347192e2017-04-04 11:13:44 -070060 }
61
62 @Override
63 public void onStart() {
Tomasz Wasilczykd7c21d32017-04-17 17:02:06 -070064 publishBinderService(Context.RADIO_SERVICE, mServiceImpl);
Tomasz Wasilczyk347192e2017-04-04 11:13:44 -070065 }
66
Tomasz Wasilczyk6b4b6462017-07-19 10:52:28 -070067 private class ServiceImpl extends IRadioService.Stub {
Tomasz Wasilczyk32d26a32017-06-14 13:54:03 -070068 private void enforcePolicyAccess() {
69 if (PackageManager.PERMISSION_GRANTED != getContext().checkCallingPermission(
Tomasz Wasilczykdf776432017-07-21 14:07:09 -070070 Manifest.permission.ACCESS_BROADCAST_RADIO)) {
71 throw new SecurityException("ACCESS_BROADCAST_RADIO permission not granted");
Tomasz Wasilczyk32d26a32017-06-14 13:54:03 -070072 }
73 }
74
Tomasz Wasilczyk347192e2017-04-04 11:13:44 -070075 @Override
Tomasz Wasilczykd15c9df2017-06-13 10:10:36 -070076 public List<RadioManager.ModuleProperties> listModules() {
Tomasz Wasilczyk32d26a32017-06-14 13:54:03 -070077 enforcePolicyAccess();
George Lu5af724322019-03-13 17:11:21 -070078 List<RadioManager.ModuleProperties> modules = new ArrayList<>();
79 modules.addAll(mV1Modules);
80 modules.addAll(mHal2.listModules());
81 return modules;
Tomasz Wasilczykd15c9df2017-06-13 10:10:36 -070082 }
83
84 @Override
Tomasz Wasilczyk21348172017-04-20 14:02:42 -070085 public ITuner openTuner(int moduleId, RadioManager.BandConfig bandConfig,
Tomasz Wasilczyk436128f2018-01-08 16:46:09 -080086 boolean withAudio, ITunerCallback callback) throws RemoteException {
Tomasz Wasilczykf151a7b2018-01-11 16:03:46 -080087 if (DEBUG) Slog.i(TAG, "Opening module " + moduleId);
Tomasz Wasilczyk32d26a32017-06-14 13:54:03 -070088 enforcePolicyAccess();
Tomasz Wasilczyk21348172017-04-20 14:02:42 -070089 if (callback == null) {
90 throw new IllegalArgumentException("Callback must not be empty");
91 }
Tomasz Wasilczykf13b8412017-05-09 11:54:35 -070092 synchronized (mLock) {
Tomasz Wasilczykdf013262017-12-13 11:47:20 -080093 if (mHal2.hasModule(moduleId)) {
Tomasz Wasilczykca98cde2018-01-04 12:26:40 -080094 return mHal2.openSession(moduleId, bandConfig, withAudio, callback);
Tomasz Wasilczykdf013262017-12-13 11:47:20 -080095 } else {
96 return mHal1.openTuner(moduleId, bandConfig, withAudio, callback);
97 }
Tomasz Wasilczykf13b8412017-05-09 11:54:35 -070098 }
Tomasz Wasilczyk347192e2017-04-04 11:13:44 -070099 }
Tomasz Wasilczykf151a7b2018-01-11 16:03:46 -0800100
101 @Override
102 public ICloseHandle addAnnouncementListener(int[] enabledTypes,
103 IAnnouncementListener listener) {
104 if (DEBUG) {
105 Slog.i(TAG, "Adding announcement listener for " + Arrays.toString(enabledTypes));
106 }
107 Objects.requireNonNull(enabledTypes);
108 Objects.requireNonNull(listener);
109 enforcePolicyAccess();
110
111 synchronized (mLock) {
112 if (!mHal2.hasAnyModules()) {
113 Slog.i(TAG, "There are no HAL 2.x modules registered");
114 return new AnnouncementAggregator(listener);
115 }
116
117 return mHal2.addAnnouncementListener(enabledTypes, listener);
118 }
119 }
Tomasz Wasilczyk347192e2017-04-04 11:13:44 -0700120 }
121}