blob: 406231ae289fbed533cb054730cbb60fea4c068d [file] [log] [blame]
Tomasz Wasilczykd65b3ca2017-12-13 08:26:25 -08001/**
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.hal2;
18
19import android.annotation.NonNull;
Tomasz Wasilczykca98cde2018-01-04 12:26:40 -080020import android.annotation.Nullable;
Tomasz Wasilczykf151a7b2018-01-11 16:03:46 -080021import android.hardware.radio.IAnnouncementListener;
22import android.hardware.radio.ICloseHandle;
Tomasz Wasilczykf58305d2017-12-28 14:03:15 -080023import android.hardware.radio.ITuner;
24import android.hardware.radio.ITunerCallback;
Tomasz Wasilczykd65b3ca2017-12-13 08:26:25 -080025import android.hardware.radio.RadioManager;
26import android.hardware.broadcastradio.V2_0.IBroadcastRadio;
27import android.hidl.manager.V1_0.IServiceManager;
28import android.os.RemoteException;
29import android.util.Slog;
30
31import java.util.Collection;
32import java.util.Collections;
33import java.util.HashMap;
34import java.util.List;
35import java.util.Map;
Tomasz Wasilczykf58305d2017-12-28 14:03:15 -080036import java.util.Objects;
Tomasz Wasilczykd65b3ca2017-12-13 08:26:25 -080037import java.util.stream.Collectors;
38
39public class BroadcastRadioService {
40 private static final String TAG = "BcRadio2Srv";
41
42 private final Map<Integer, RadioModule> mModules = new HashMap<>();
43
44 private static @NonNull List<String> listByInterface(@NonNull String fqName) {
45 try {
46 IServiceManager manager = IServiceManager.getService();
47 if (manager == null) {
48 Slog.e(TAG, "Failed to get HIDL Service Manager");
49 return Collections.emptyList();
50 }
51
52 List<String> list = manager.listByInterface(fqName);
53 if (list == null) {
54 Slog.e(TAG, "Didn't get interface list from HIDL Service Manager");
55 return Collections.emptyList();
56 }
57 return list;
58 } catch (RemoteException ex) {
59 Slog.e(TAG, "Failed fetching interface list", ex);
60 return Collections.emptyList();
61 }
62 }
63
64 public @NonNull Collection<RadioManager.ModuleProperties> loadModules(int idx) {
65 Slog.v(TAG, "loadModules(" + idx + ")");
66
67 for (String serviceName : listByInterface(IBroadcastRadio.kInterfaceName)) {
68 Slog.v(TAG, "checking service: " + serviceName);
69
70 RadioModule module = RadioModule.tryLoadingModule(idx, serviceName);
71 if (module != null) {
72 Slog.i(TAG, "loaded broadcast radio module " + idx + ": " +
73 serviceName + " (HAL 2.0)");
74 mModules.put(idx++, module);
75 }
76 }
77
78 return mModules.values().stream().map(module -> module.mProperties).
79 collect(Collectors.toList());
80 }
Tomasz Wasilczykdf013262017-12-13 11:47:20 -080081
82 public boolean hasModule(int id) {
83 return mModules.containsKey(id);
84 }
Tomasz Wasilczykf58305d2017-12-28 14:03:15 -080085
Tomasz Wasilczykf151a7b2018-01-11 16:03:46 -080086 public boolean hasAnyModules() {
87 return !mModules.isEmpty();
88 }
89
Tomasz Wasilczykca98cde2018-01-04 12:26:40 -080090 public ITuner openSession(int moduleId, @Nullable RadioManager.BandConfig legacyConfig,
Tomasz Wasilczyk436128f2018-01-08 16:46:09 -080091 boolean withAudio, @NonNull ITunerCallback callback) throws RemoteException {
Tomasz Wasilczykf58305d2017-12-28 14:03:15 -080092 Objects.requireNonNull(callback);
93
Tomasz Wasilczykca98cde2018-01-04 12:26:40 -080094 if (!withAudio) {
95 throw new IllegalArgumentException("Non-audio sessions not supported with HAL 2.x");
96 }
97
Tomasz Wasilczykf58305d2017-12-28 14:03:15 -080098 RadioModule module = mModules.get(moduleId);
99 if (module == null) {
100 throw new IllegalArgumentException("Invalid module ID");
101 }
102
Tomasz Wasilczykca98cde2018-01-04 12:26:40 -0800103 TunerSession session = module.openSession(callback);
104 session.setConfiguration(legacyConfig);
105 return session;
Tomasz Wasilczykf58305d2017-12-28 14:03:15 -0800106 }
Tomasz Wasilczykf151a7b2018-01-11 16:03:46 -0800107
108 public ICloseHandle addAnnouncementListener(@NonNull int[] enabledTypes,
109 @NonNull IAnnouncementListener listener) {
110 AnnouncementAggregator aggregator = new AnnouncementAggregator(listener);
111 boolean anySupported = false;
112 for (RadioModule module : mModules.values()) {
113 try {
114 aggregator.watchModule(module, enabledTypes);
115 anySupported = true;
116 } catch (UnsupportedOperationException ex) {
117 Slog.v(TAG, "Announcements not supported for this module", ex);
118 }
119 }
120 if (!anySupported) {
121 Slog.i(TAG, "There are no HAL modules that support announcements");
122 }
123 return aggregator;
124 }
Tomasz Wasilczykd65b3ca2017-12-13 08:26:25 -0800125}