Kyunglyul Hyun | d51666d | 2019-04-11 04:08:40 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2019 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 | |
Hyundo Moon | 5de706f | 2020-02-03 20:16:33 +0900 | [diff] [blame] | 17 | package com.android.mediaroutertest; |
Kyunglyul Hyun | d51666d | 2019-04-11 04:08:40 +0000 | [diff] [blame] | 18 | |
Kyunglyul Hyun | 5161b37 | 2020-02-05 18:45:35 +0900 | [diff] [blame] | 19 | import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE; |
Kyunglyul Hyun | 8828c89 | 2020-02-17 20:49:58 +0900 | [diff] [blame] | 20 | import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER; |
| 21 | import static android.media.MediaRoute2Info.TYPE_REMOTE_TV; |
Kyunglyul Hyun | 3aeabe0 | 2019-12-20 19:42:39 +0900 | [diff] [blame] | 22 | |
Kyunglyul Hyun | c943f21 | 2020-02-14 17:58:23 +0900 | [diff] [blame] | 23 | import android.annotation.NonNull; |
Hyundo Moon | 84e027d | 2020-01-16 17:39:05 +0900 | [diff] [blame] | 24 | import android.annotation.Nullable; |
Kyunglyul Hyun | d51666d | 2019-04-11 04:08:40 +0000 | [diff] [blame] | 25 | import android.content.Intent; |
Kyunglyul Hyun | 3aedf02 | 2019-04-15 16:38:19 +0900 | [diff] [blame] | 26 | import android.media.MediaRoute2Info; |
Kyunglyul Hyun | d51666d | 2019-04-11 04:08:40 +0000 | [diff] [blame] | 27 | import android.media.MediaRoute2ProviderService; |
Hyundo Moon | f829e6f | 2020-01-11 19:31:35 +0900 | [diff] [blame] | 28 | import android.media.RoutingSessionInfo; |
Hyundo Moon | 84e027d | 2020-01-16 17:39:05 +0900 | [diff] [blame] | 29 | import android.os.Bundle; |
Kyunglyul Hyun | d51666d | 2019-04-11 04:08:40 +0000 | [diff] [blame] | 30 | import android.os.IBinder; |
Hyundo Moon | 63a0540 | 2019-12-19 20:13:56 +0900 | [diff] [blame] | 31 | import android.text.TextUtils; |
Kyunglyul Hyun | d51666d | 2019-04-11 04:08:40 +0000 | [diff] [blame] | 32 | |
Kyunglyul Hyun | 3aedf02 | 2019-04-15 16:38:19 +0900 | [diff] [blame] | 33 | import java.util.HashMap; |
| 34 | import java.util.Map; |
Kyunglyul Hyun | c943f21 | 2020-02-14 17:58:23 +0900 | [diff] [blame] | 35 | import java.util.Objects; |
| 36 | |
| 37 | import javax.annotation.concurrent.GuardedBy; |
Kyunglyul Hyun | 3aedf02 | 2019-04-15 16:38:19 +0900 | [diff] [blame] | 38 | |
Hyundo Moon | 1c888e2 | 2020-03-15 19:46:41 +0900 | [diff] [blame] | 39 | public class StubMediaRoute2ProviderService extends MediaRoute2ProviderService { |
Hyundo Moon | 7d3ab33 | 2019-10-16 11:09:56 +0900 | [diff] [blame] | 40 | private static final String TAG = "SampleMR2ProviderSvc"; |
Kyunglyul Hyun | c943f21 | 2020-02-14 17:58:23 +0900 | [diff] [blame] | 41 | private static final Object sLock = new Object(); |
Kyunglyul Hyun | 3aedf02 | 2019-04-15 16:38:19 +0900 | [diff] [blame] | 42 | |
Kyunglyul Hyun | caae8dc | 2019-04-29 15:45:23 +0900 | [diff] [blame] | 43 | public static final String ROUTE_ID1 = "route_id1"; |
| 44 | public static final String ROUTE_NAME1 = "Sample Route 1"; |
| 45 | public static final String ROUTE_ID2 = "route_id2"; |
| 46 | public static final String ROUTE_NAME2 = "Sample Route 2"; |
Hyundo Moon | 63a0540 | 2019-12-19 20:13:56 +0900 | [diff] [blame] | 47 | public static final String ROUTE_ID3_SESSION_CREATION_FAILED = |
| 48 | "route_id3_session_creation_failed"; |
| 49 | public static final String ROUTE_NAME3 = "Sample Route 3 - Session creation failed"; |
Hyundo Moon | 0a92657 | 2019-12-28 15:01:21 +0900 | [diff] [blame] | 50 | public static final String ROUTE_ID4_TO_SELECT_AND_DESELECT = |
| 51 | "route_id4_to_select_and_deselect"; |
| 52 | public static final String ROUTE_NAME4 = "Sample Route 4 - Route to select and deselect"; |
| 53 | public static final String ROUTE_ID5_TO_TRANSFER_TO = "route_id5_to_transfer_to"; |
| 54 | public static final String ROUTE_NAME5 = "Sample Route 5 - Route to transfer to"; |
Kyunglyul Hyun | e23e5ed | 2019-07-15 16:06:26 +0900 | [diff] [blame] | 55 | |
Kyunglyul Hyun | 8df5fb6 | 2020-06-03 16:52:04 +0900 | [diff] [blame] | 56 | public static final String ROUTE_ID6_TO_BE_IGNORED = "route_id6_to_be_ignored"; |
| 57 | public static final String ROUTE_NAME6 = "Sample Route 6 - Route to be ignored"; |
| 58 | |
Kyunglyul Hyun | 616096e | 2020-01-09 16:15:03 +0900 | [diff] [blame] | 59 | public static final String ROUTE_ID_SPECIAL_FEATURE = "route_special_feature"; |
| 60 | public static final String ROUTE_NAME_SPECIAL_FEATURE = "Special Feature Route"; |
Kyunglyul Hyun | e23e5ed | 2019-07-15 16:06:26 +0900 | [diff] [blame] | 61 | |
Kyunglyul Hyun | 9b10a64 | 2019-10-08 15:29:23 +0900 | [diff] [blame] | 62 | public static final int VOLUME_MAX = 100; |
Kyunglyul Hyun | 5161b37 | 2020-02-05 18:45:35 +0900 | [diff] [blame] | 63 | public static final int SESSION_VOLUME_MAX = 50; |
| 64 | public static final int SESSION_VOLUME_INITIAL = 20; |
Kyunglyul Hyun | 9b10a64 | 2019-10-08 15:29:23 +0900 | [diff] [blame] | 65 | public static final String ROUTE_ID_FIXED_VOLUME = "route_fixed_volume"; |
| 66 | public static final String ROUTE_NAME_FIXED_VOLUME = "Fixed Volume Route"; |
| 67 | public static final String ROUTE_ID_VARIABLE_VOLUME = "route_variable_volume"; |
| 68 | public static final String ROUTE_NAME_VARIABLE_VOLUME = "Variable Volume Route"; |
| 69 | |
Kyunglyul Hyun | 616096e | 2020-01-09 16:15:03 +0900 | [diff] [blame] | 70 | public static final String FEATURE_SAMPLE = |
Kyunglyul Hyun | 350d7b4 | 2020-04-17 23:09:08 +0900 | [diff] [blame] | 71 | "com.android.mediaroutertest.FEATURE_SAMPLE"; |
Kyunglyul Hyun | 616096e | 2020-01-09 16:15:03 +0900 | [diff] [blame] | 72 | public static final String FEATURE_SPECIAL = |
Kyunglyul Hyun | 350d7b4 | 2020-04-17 23:09:08 +0900 | [diff] [blame] | 73 | "com.android.mediaroutertest..FEATURE_SPECIAL"; |
Kyunglyul Hyun | e23e5ed | 2019-07-15 16:06:26 +0900 | [diff] [blame] | 74 | |
Kyunglyul Hyun | 3aedf02 | 2019-04-15 16:38:19 +0900 | [diff] [blame] | 75 | Map<String, MediaRoute2Info> mRoutes = new HashMap<>(); |
Hyundo Moon | f829e6f | 2020-01-11 19:31:35 +0900 | [diff] [blame] | 76 | Map<String, String> mRouteIdToSessionId = new HashMap<>(); |
Hyundo Moon | a64ca9e | 2019-12-27 17:41:17 +0900 | [diff] [blame] | 77 | private int mNextSessionId = 1000; |
Kyunglyul Hyun | 3aedf02 | 2019-04-15 16:38:19 +0900 | [diff] [blame] | 78 | |
Kyunglyul Hyun | c943f21 | 2020-02-14 17:58:23 +0900 | [diff] [blame] | 79 | @GuardedBy("sLock") |
Hyundo Moon | 1c888e2 | 2020-03-15 19:46:41 +0900 | [diff] [blame] | 80 | private static StubMediaRoute2ProviderService sInstance; |
Hyundo Moon | 0fa60e8 | 2020-02-14 11:44:45 +0900 | [diff] [blame] | 81 | private Proxy mProxy; |
Kyunglyul Hyun | 6a2f1d6 | 2020-05-19 23:00:17 +0900 | [diff] [blame] | 82 | private Spy mSpy; |
Kyunglyul Hyun | c943f21 | 2020-02-14 17:58:23 +0900 | [diff] [blame] | 83 | |
Kyunglyul Hyun | 3aedf02 | 2019-04-15 16:38:19 +0900 | [diff] [blame] | 84 | private void initializeRoutes() { |
| 85 | MediaRoute2Info route1 = new MediaRoute2Info.Builder(ROUTE_ID1, ROUTE_NAME1) |
Kyunglyul Hyun | 616096e | 2020-01-09 16:15:03 +0900 | [diff] [blame] | 86 | .addFeature(FEATURE_SAMPLE) |
Kyunglyul Hyun | 8828c89 | 2020-02-17 20:49:58 +0900 | [diff] [blame] | 87 | .setType(TYPE_REMOTE_TV) |
Kyunglyul Hyun | 3aedf02 | 2019-04-15 16:38:19 +0900 | [diff] [blame] | 88 | .build(); |
Kyunglyul Hyun | caae8dc | 2019-04-29 15:45:23 +0900 | [diff] [blame] | 89 | MediaRoute2Info route2 = new MediaRoute2Info.Builder(ROUTE_ID2, ROUTE_NAME2) |
Kyunglyul Hyun | 616096e | 2020-01-09 16:15:03 +0900 | [diff] [blame] | 90 | .addFeature(FEATURE_SAMPLE) |
Kyunglyul Hyun | 8828c89 | 2020-02-17 20:49:58 +0900 | [diff] [blame] | 91 | .setType(TYPE_REMOTE_SPEAKER) |
Kyunglyul Hyun | caae8dc | 2019-04-29 15:45:23 +0900 | [diff] [blame] | 92 | .build(); |
Hyundo Moon | 63a0540 | 2019-12-19 20:13:56 +0900 | [diff] [blame] | 93 | MediaRoute2Info route3 = new MediaRoute2Info.Builder( |
| 94 | ROUTE_ID3_SESSION_CREATION_FAILED, ROUTE_NAME3) |
Kyunglyul Hyun | 616096e | 2020-01-09 16:15:03 +0900 | [diff] [blame] | 95 | .addFeature(FEATURE_SAMPLE) |
Hyundo Moon | 63a0540 | 2019-12-19 20:13:56 +0900 | [diff] [blame] | 96 | .build(); |
Hyundo Moon | 0a92657 | 2019-12-28 15:01:21 +0900 | [diff] [blame] | 97 | MediaRoute2Info route4 = new MediaRoute2Info.Builder( |
| 98 | ROUTE_ID4_TO_SELECT_AND_DESELECT, ROUTE_NAME4) |
Kyunglyul Hyun | 616096e | 2020-01-09 16:15:03 +0900 | [diff] [blame] | 99 | .addFeature(FEATURE_SAMPLE) |
Hyundo Moon | 0a92657 | 2019-12-28 15:01:21 +0900 | [diff] [blame] | 100 | .build(); |
| 101 | MediaRoute2Info route5 = new MediaRoute2Info.Builder( |
| 102 | ROUTE_ID5_TO_TRANSFER_TO, ROUTE_NAME5) |
Kyunglyul Hyun | 616096e | 2020-01-09 16:15:03 +0900 | [diff] [blame] | 103 | .addFeature(FEATURE_SAMPLE) |
Hyundo Moon | 0a92657 | 2019-12-28 15:01:21 +0900 | [diff] [blame] | 104 | .build(); |
Kyunglyul Hyun | 8df5fb6 | 2020-06-03 16:52:04 +0900 | [diff] [blame] | 105 | MediaRoute2Info route6 = new MediaRoute2Info.Builder( |
| 106 | ROUTE_ID6_TO_BE_IGNORED, ROUTE_NAME6) |
| 107 | .addFeature(FEATURE_SAMPLE) |
| 108 | .build(); |
Kyunglyul Hyun | e23e5ed | 2019-07-15 16:06:26 +0900 | [diff] [blame] | 109 | MediaRoute2Info routeSpecial = |
Kyunglyul Hyun | 616096e | 2020-01-09 16:15:03 +0900 | [diff] [blame] | 110 | new MediaRoute2Info.Builder(ROUTE_ID_SPECIAL_FEATURE, ROUTE_NAME_SPECIAL_FEATURE) |
| 111 | .addFeature(FEATURE_SAMPLE) |
| 112 | .addFeature(FEATURE_SPECIAL) |
Kyunglyul Hyun | e23e5ed | 2019-07-15 16:06:26 +0900 | [diff] [blame] | 113 | .build(); |
Kyunglyul Hyun | 9b10a64 | 2019-10-08 15:29:23 +0900 | [diff] [blame] | 114 | MediaRoute2Info fixedVolumeRoute = |
| 115 | new MediaRoute2Info.Builder(ROUTE_ID_FIXED_VOLUME, ROUTE_NAME_FIXED_VOLUME) |
Kyunglyul Hyun | 616096e | 2020-01-09 16:15:03 +0900 | [diff] [blame] | 116 | .addFeature(FEATURE_SAMPLE) |
Kyunglyul Hyun | 9b10a64 | 2019-10-08 15:29:23 +0900 | [diff] [blame] | 117 | .setVolumeHandling(MediaRoute2Info.PLAYBACK_VOLUME_FIXED) |
| 118 | .build(); |
| 119 | MediaRoute2Info variableVolumeRoute = |
| 120 | new MediaRoute2Info.Builder(ROUTE_ID_VARIABLE_VOLUME, ROUTE_NAME_VARIABLE_VOLUME) |
Kyunglyul Hyun | 616096e | 2020-01-09 16:15:03 +0900 | [diff] [blame] | 121 | .addFeature(FEATURE_SAMPLE) |
Kyunglyul Hyun | 9b10a64 | 2019-10-08 15:29:23 +0900 | [diff] [blame] | 122 | .setVolumeHandling(MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE) |
| 123 | .setVolumeMax(VOLUME_MAX) |
| 124 | .build(); |
| 125 | |
Kyunglyul Hyun | 3aedf02 | 2019-04-15 16:38:19 +0900 | [diff] [blame] | 126 | mRoutes.put(route1.getId(), route1); |
Kyunglyul Hyun | caae8dc | 2019-04-29 15:45:23 +0900 | [diff] [blame] | 127 | mRoutes.put(route2.getId(), route2); |
Hyundo Moon | 63a0540 | 2019-12-19 20:13:56 +0900 | [diff] [blame] | 128 | mRoutes.put(route3.getId(), route3); |
Hyundo Moon | 0a92657 | 2019-12-28 15:01:21 +0900 | [diff] [blame] | 129 | mRoutes.put(route4.getId(), route4); |
| 130 | mRoutes.put(route5.getId(), route5); |
Kyunglyul Hyun | 8df5fb6 | 2020-06-03 16:52:04 +0900 | [diff] [blame] | 131 | mRoutes.put(route6.getId(), route6); |
Kyunglyul Hyun | c943f21 | 2020-02-14 17:58:23 +0900 | [diff] [blame] | 132 | |
Kyunglyul Hyun | e23e5ed | 2019-07-15 16:06:26 +0900 | [diff] [blame] | 133 | mRoutes.put(routeSpecial.getId(), routeSpecial); |
Kyunglyul Hyun | 9b10a64 | 2019-10-08 15:29:23 +0900 | [diff] [blame] | 134 | mRoutes.put(fixedVolumeRoute.getId(), fixedVolumeRoute); |
| 135 | mRoutes.put(variableVolumeRoute.getId(), variableVolumeRoute); |
Kyunglyul Hyun | 3aedf02 | 2019-04-15 16:38:19 +0900 | [diff] [blame] | 136 | } |
| 137 | |
Hyundo Moon | 1c888e2 | 2020-03-15 19:46:41 +0900 | [diff] [blame] | 138 | public static StubMediaRoute2ProviderService getInstance() { |
Kyunglyul Hyun | c943f21 | 2020-02-14 17:58:23 +0900 | [diff] [blame] | 139 | synchronized (sLock) { |
| 140 | return sInstance; |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | /** |
| 145 | * Adds a route and publishes it. It could replace a route in the provider if |
| 146 | * they have the same route id. |
| 147 | */ |
| 148 | public void addRoute(@NonNull MediaRoute2Info route) { |
| 149 | Objects.requireNonNull(route, "route must not be null"); |
| 150 | mRoutes.put(route.getOriginalId(), route); |
| 151 | publishRoutes(); |
| 152 | } |
| 153 | |
| 154 | /** |
| 155 | * Removes a route and publishes it. |
| 156 | */ |
| 157 | public void removeRoute(@NonNull String routeId) { |
| 158 | Objects.requireNonNull(routeId, "routeId must not be null"); |
| 159 | MediaRoute2Info route = mRoutes.get(routeId); |
| 160 | if (route != null) { |
| 161 | mRoutes.remove(routeId); |
| 162 | publishRoutes(); |
| 163 | } |
| 164 | } |
| 165 | |
Kyunglyul Hyun | 3aedf02 | 2019-04-15 16:38:19 +0900 | [diff] [blame] | 166 | @Override |
| 167 | public void onCreate() { |
Kyunglyul Hyun | c943f21 | 2020-02-14 17:58:23 +0900 | [diff] [blame] | 168 | synchronized (sLock) { |
| 169 | sInstance = this; |
| 170 | } |
Kyunglyul Hyun | 3aedf02 | 2019-04-15 16:38:19 +0900 | [diff] [blame] | 171 | initializeRoutes(); |
| 172 | } |
| 173 | |
Kyunglyul Hyun | d51666d | 2019-04-11 04:08:40 +0000 | [diff] [blame] | 174 | @Override |
Kyunglyul Hyun | c943f21 | 2020-02-14 17:58:23 +0900 | [diff] [blame] | 175 | public void onDestroy() { |
| 176 | super.onDestroy(); |
| 177 | synchronized (sLock) { |
| 178 | if (sInstance == this) { |
| 179 | sInstance = null; |
| 180 | } |
| 181 | } |
| 182 | } |
| 183 | |
| 184 | @Override |
Kyunglyul Hyun | d51666d | 2019-04-11 04:08:40 +0000 | [diff] [blame] | 185 | public IBinder onBind(Intent intent) { |
Kyunglyul Hyun | 3aedf02 | 2019-04-15 16:38:19 +0900 | [diff] [blame] | 186 | publishRoutes(); |
Kyunglyul Hyun | d51666d | 2019-04-11 04:08:40 +0000 | [diff] [blame] | 187 | return super.onBind(intent); |
| 188 | } |
| 189 | |
| 190 | @Override |
Hyundo Moon | 0fa60e8 | 2020-02-14 11:44:45 +0900 | [diff] [blame] | 191 | public void onSetRouteVolume(long requestId, String routeId, int volume) { |
| 192 | Proxy proxy = mProxy; |
| 193 | if (proxy != null) { |
| 194 | proxy.onSetRouteVolume(routeId, volume, requestId); |
| 195 | return; |
| 196 | } |
| 197 | |
Kyunglyul Hyun | 5a8dedc | 2019-10-10 14:09:44 +0900 | [diff] [blame] | 198 | MediaRoute2Info route = mRoutes.get(routeId); |
| 199 | if (route == null) { |
| 200 | return; |
| 201 | } |
Kyunglyul Hyun | 5161b37 | 2020-02-05 18:45:35 +0900 | [diff] [blame] | 202 | volume = Math.max(0, Math.min(volume, route.getVolumeMax())); |
Kyunglyul Hyun | 5a8dedc | 2019-10-10 14:09:44 +0900 | [diff] [blame] | 203 | mRoutes.put(routeId, new MediaRoute2Info.Builder(route) |
| 204 | .setVolume(volume) |
| 205 | .build()); |
| 206 | publishRoutes(); |
| 207 | } |
| 208 | |
| 209 | @Override |
Hyundo Moon | 0fa60e8 | 2020-02-14 11:44:45 +0900 | [diff] [blame] | 210 | public void onSetSessionVolume(long requestId, String sessionId, int volume) { |
Kyunglyul Hyun | 5161b37 | 2020-02-05 18:45:35 +0900 | [diff] [blame] | 211 | RoutingSessionInfo sessionInfo = getSessionInfo(sessionId); |
| 212 | if (sessionInfo == null) { |
| 213 | return; |
| 214 | } |
| 215 | volume = Math.max(0, Math.min(volume, sessionInfo.getVolumeMax())); |
| 216 | RoutingSessionInfo newSessionInfo = new RoutingSessionInfo.Builder(sessionInfo) |
| 217 | .setVolume(volume) |
| 218 | .build(); |
| 219 | notifySessionUpdated(newSessionInfo); |
| 220 | } |
| 221 | |
| 222 | @Override |
Hyundo Moon | 0fa60e8 | 2020-02-14 11:44:45 +0900 | [diff] [blame] | 223 | public void onCreateSession(long requestId, String packageName, String routeId, |
Hyundo Moon | 84e027d | 2020-01-16 17:39:05 +0900 | [diff] [blame] | 224 | @Nullable Bundle sessionHints) { |
Kyunglyul Hyun | cb8894d | 2019-12-27 14:24:46 +0900 | [diff] [blame] | 225 | MediaRoute2Info route = mRoutes.get(routeId); |
| 226 | if (route == null || TextUtils.equals(ROUTE_ID3_SESSION_CREATION_FAILED, routeId)) { |
Hyundo Moon | 7c2059c | 2020-02-27 19:01:52 +0900 | [diff] [blame] | 227 | notifyRequestFailed(requestId, REASON_UNKNOWN_ERROR); |
Hyundo Moon | 63a0540 | 2019-12-19 20:13:56 +0900 | [diff] [blame] | 228 | return; |
| 229 | } |
Kyunglyul Hyun | 8df5fb6 | 2020-06-03 16:52:04 +0900 | [diff] [blame] | 230 | // Ignores the request intentionally for testing |
| 231 | if (TextUtils.equals(ROUTE_ID6_TO_BE_IGNORED, routeId)) { |
| 232 | return; |
| 233 | } |
Hyundo Moon | 9be3548 | 2019-12-30 17:33:13 +0900 | [diff] [blame] | 234 | maybeDeselectRoute(routeId); |
Kyunglyul Hyun | cb8894d | 2019-12-27 14:24:46 +0900 | [diff] [blame] | 235 | |
Hyundo Moon | b26c4b2 | 2020-01-08 19:44:43 +0900 | [diff] [blame] | 236 | final String sessionId = String.valueOf(mNextSessionId); |
Hyundo Moon | a64ca9e | 2019-12-27 17:41:17 +0900 | [diff] [blame] | 237 | mNextSessionId++; |
Kyunglyul Hyun | cb8894d | 2019-12-27 14:24:46 +0900 | [diff] [blame] | 238 | |
| 239 | mRoutes.put(routeId, new MediaRoute2Info.Builder(route) |
| 240 | .setClientPackageName(packageName) |
| 241 | .build()); |
Hyundo Moon | f829e6f | 2020-01-11 19:31:35 +0900 | [diff] [blame] | 242 | mRouteIdToSessionId.put(routeId, sessionId); |
Hyundo Moon | 63a0540 | 2019-12-19 20:13:56 +0900 | [diff] [blame] | 243 | |
Hyundo Moon | dc79a7a | 2020-01-16 15:18:33 +0900 | [diff] [blame] | 244 | RoutingSessionInfo sessionInfo = new RoutingSessionInfo.Builder(sessionId, packageName) |
Kyunglyul Hyun | 24cc66f | 2019-12-19 19:04:20 +0900 | [diff] [blame] | 245 | .addSelectedRoute(routeId) |
Hyundo Moon | 0a92657 | 2019-12-28 15:01:21 +0900 | [diff] [blame] | 246 | .addSelectableRoute(ROUTE_ID4_TO_SELECT_AND_DESELECT) |
Kyunglyul Hyun | 6e0c08b | 2020-02-14 15:44:18 +0900 | [diff] [blame] | 247 | .addTransferableRoute(ROUTE_ID5_TO_TRANSFER_TO) |
Kyunglyul Hyun | 5161b37 | 2020-02-05 18:45:35 +0900 | [diff] [blame] | 248 | .setVolumeHandling(PLAYBACK_VOLUME_VARIABLE) |
| 249 | .setVolumeMax(SESSION_VOLUME_MAX) |
| 250 | .setVolume(SESSION_VOLUME_INITIAL) |
Hyundo Moon | 84e027d | 2020-01-16 17:39:05 +0900 | [diff] [blame] | 251 | // Set control hints with given sessionHints |
| 252 | .setControlHints(sessionHints) |
Kyunglyul Hyun | 24cc66f | 2019-12-19 19:04:20 +0900 | [diff] [blame] | 253 | .build(); |
Hyundo Moon | f8e49f4b | 2020-03-06 17:19:42 +0900 | [diff] [blame] | 254 | notifySessionCreated(requestId, sessionInfo); |
Kyunglyul Hyun | cb8894d | 2019-12-27 14:24:46 +0900 | [diff] [blame] | 255 | publishRoutes(); |
Kyunglyul Hyun | 24cc66f | 2019-12-19 19:04:20 +0900 | [diff] [blame] | 256 | } |
| 257 | |
| 258 | @Override |
Hyundo Moon | 0fa60e8 | 2020-02-14 11:44:45 +0900 | [diff] [blame] | 259 | public void onReleaseSession(long requestId, String sessionId) { |
Kyunglyul Hyun | 6a2f1d6 | 2020-05-19 23:00:17 +0900 | [diff] [blame] | 260 | Spy spy = mSpy; |
| 261 | if (spy != null) { |
| 262 | spy.onReleaseSession(requestId, sessionId); |
| 263 | } |
| 264 | |
Hyundo Moon | 6e30f1b | 2020-01-13 19:50:27 +0900 | [diff] [blame] | 265 | RoutingSessionInfo sessionInfo = getSessionInfo(sessionId); |
| 266 | if (sessionInfo == null) { |
| 267 | return; |
| 268 | } |
| 269 | |
| 270 | for (String routeId : sessionInfo.getSelectedRoutes()) { |
Hyundo Moon | f829e6f | 2020-01-11 19:31:35 +0900 | [diff] [blame] | 271 | mRouteIdToSessionId.remove(routeId); |
Kyunglyul Hyun | cb8894d | 2019-12-27 14:24:46 +0900 | [diff] [blame] | 272 | MediaRoute2Info route = mRoutes.get(routeId); |
| 273 | if (route != null) { |
| 274 | mRoutes.put(routeId, new MediaRoute2Info.Builder(route) |
| 275 | .setClientPackageName(null) |
| 276 | .build()); |
| 277 | } |
| 278 | } |
Hyundo Moon | 6e30f1b | 2020-01-13 19:50:27 +0900 | [diff] [blame] | 279 | notifySessionReleased(sessionId); |
Kyunglyul Hyun | c658383 | 2020-01-17 11:11:46 +0000 | [diff] [blame] | 280 | publishRoutes(); |
Kyunglyul Hyun | cb8894d | 2019-12-27 14:24:46 +0900 | [diff] [blame] | 281 | } |
Kyunglyul Hyun | 24cc66f | 2019-12-19 19:04:20 +0900 | [diff] [blame] | 282 | |
| 283 | @Override |
Hyundo Moon | 0fa60e8 | 2020-02-14 11:44:45 +0900 | [diff] [blame] | 284 | public void onSelectRoute(long requestId, String sessionId, String routeId) { |
Hyundo Moon | f829e6f | 2020-01-11 19:31:35 +0900 | [diff] [blame] | 285 | RoutingSessionInfo sessionInfo = getSessionInfo(sessionId); |
Kyunglyul Hyun | cb8894d | 2019-12-27 14:24:46 +0900 | [diff] [blame] | 286 | MediaRoute2Info route = mRoutes.get(routeId); |
| 287 | if (route == null || sessionInfo == null) { |
| 288 | return; |
| 289 | } |
Hyundo Moon | 9be3548 | 2019-12-30 17:33:13 +0900 | [diff] [blame] | 290 | maybeDeselectRoute(routeId); |
Kyunglyul Hyun | cb8894d | 2019-12-27 14:24:46 +0900 | [diff] [blame] | 291 | |
| 292 | mRoutes.put(routeId, new MediaRoute2Info.Builder(route) |
Hyundo Moon | b26c4b2 | 2020-01-08 19:44:43 +0900 | [diff] [blame] | 293 | .setClientPackageName(sessionInfo.getClientPackageName()) |
Kyunglyul Hyun | cb8894d | 2019-12-27 14:24:46 +0900 | [diff] [blame] | 294 | .build()); |
Hyundo Moon | f829e6f | 2020-01-11 19:31:35 +0900 | [diff] [blame] | 295 | mRouteIdToSessionId.put(routeId, sessionId); |
Kyunglyul Hyun | cb8894d | 2019-12-27 14:24:46 +0900 | [diff] [blame] | 296 | |
Hyundo Moon | f829e6f | 2020-01-11 19:31:35 +0900 | [diff] [blame] | 297 | RoutingSessionInfo newSessionInfo = new RoutingSessionInfo.Builder(sessionInfo) |
Kyunglyul Hyun | 24cc66f | 2019-12-19 19:04:20 +0900 | [diff] [blame] | 298 | .addSelectedRoute(routeId) |
Hyundo Moon | 0a92657 | 2019-12-28 15:01:21 +0900 | [diff] [blame] | 299 | .removeSelectableRoute(routeId) |
| 300 | .addDeselectableRoute(routeId) |
Kyunglyul Hyun | 24cc66f | 2019-12-19 19:04:20 +0900 | [diff] [blame] | 301 | .build(); |
Hyundo Moon | 6e30f1b | 2020-01-13 19:50:27 +0900 | [diff] [blame] | 302 | notifySessionUpdated(newSessionInfo); |
Kyunglyul Hyun | 24cc66f | 2019-12-19 19:04:20 +0900 | [diff] [blame] | 303 | } |
| 304 | |
| 305 | @Override |
Hyundo Moon | 0fa60e8 | 2020-02-14 11:44:45 +0900 | [diff] [blame] | 306 | public void onDeselectRoute(long requestId, String sessionId, String routeId) { |
Hyundo Moon | f829e6f | 2020-01-11 19:31:35 +0900 | [diff] [blame] | 307 | RoutingSessionInfo sessionInfo = getSessionInfo(sessionId); |
Kyunglyul Hyun | cb8894d | 2019-12-27 14:24:46 +0900 | [diff] [blame] | 308 | MediaRoute2Info route = mRoutes.get(routeId); |
| 309 | |
Hyundo Moon | 459dee3 | 2020-01-11 14:06:46 +0900 | [diff] [blame] | 310 | if (sessionInfo == null || route == null |
| 311 | || !sessionInfo.getSelectedRoutes().contains(routeId)) { |
Kyunglyul Hyun | cb8894d | 2019-12-27 14:24:46 +0900 | [diff] [blame] | 312 | return; |
| 313 | } |
Hyundo Moon | 459dee3 | 2020-01-11 14:06:46 +0900 | [diff] [blame] | 314 | |
Hyundo Moon | f829e6f | 2020-01-11 19:31:35 +0900 | [diff] [blame] | 315 | mRouteIdToSessionId.remove(routeId); |
Kyunglyul Hyun | cb8894d | 2019-12-27 14:24:46 +0900 | [diff] [blame] | 316 | mRoutes.put(routeId, new MediaRoute2Info.Builder(route) |
| 317 | .setClientPackageName(null) |
| 318 | .build()); |
| 319 | |
Hyundo Moon | 459dee3 | 2020-01-11 14:06:46 +0900 | [diff] [blame] | 320 | if (sessionInfo.getSelectedRoutes().size() == 1) { |
Hyundo Moon | 6e30f1b | 2020-01-13 19:50:27 +0900 | [diff] [blame] | 321 | notifySessionReleased(sessionId); |
Hyundo Moon | 459dee3 | 2020-01-11 14:06:46 +0900 | [diff] [blame] | 322 | return; |
| 323 | } |
| 324 | |
Hyundo Moon | f829e6f | 2020-01-11 19:31:35 +0900 | [diff] [blame] | 325 | RoutingSessionInfo newSessionInfo = new RoutingSessionInfo.Builder(sessionInfo) |
Kyunglyul Hyun | 24cc66f | 2019-12-19 19:04:20 +0900 | [diff] [blame] | 326 | .removeSelectedRoute(routeId) |
Hyundo Moon | 0a92657 | 2019-12-28 15:01:21 +0900 | [diff] [blame] | 327 | .addSelectableRoute(routeId) |
| 328 | .removeDeselectableRoute(routeId) |
Kyunglyul Hyun | 24cc66f | 2019-12-19 19:04:20 +0900 | [diff] [blame] | 329 | .build(); |
Hyundo Moon | 6e30f1b | 2020-01-13 19:50:27 +0900 | [diff] [blame] | 330 | notifySessionUpdated(newSessionInfo); |
Kyunglyul Hyun | 24cc66f | 2019-12-19 19:04:20 +0900 | [diff] [blame] | 331 | } |
| 332 | |
| 333 | @Override |
Hyundo Moon | 0fa60e8 | 2020-02-14 11:44:45 +0900 | [diff] [blame] | 334 | public void onTransferToRoute(long requestId, String sessionId, String routeId) { |
Hyundo Moon | f829e6f | 2020-01-11 19:31:35 +0900 | [diff] [blame] | 335 | RoutingSessionInfo sessionInfo = getSessionInfo(sessionId); |
Kyunglyul Hyun | c658383 | 2020-01-17 11:11:46 +0000 | [diff] [blame] | 336 | MediaRoute2Info route = mRoutes.get(routeId); |
| 337 | |
| 338 | if (sessionInfo == null || route == null) { |
| 339 | return; |
| 340 | } |
| 341 | |
| 342 | for (String selectedRouteId : sessionInfo.getSelectedRoutes()) { |
| 343 | mRouteIdToSessionId.remove(selectedRouteId); |
| 344 | MediaRoute2Info selectedRoute = mRoutes.get(selectedRouteId); |
| 345 | if (selectedRoute != null) { |
| 346 | mRoutes.put(selectedRouteId, new MediaRoute2Info.Builder(selectedRoute) |
| 347 | .setClientPackageName(null) |
| 348 | .build()); |
| 349 | } |
| 350 | } |
| 351 | |
| 352 | mRoutes.put(routeId, new MediaRoute2Info.Builder(route) |
| 353 | .setClientPackageName(sessionInfo.getClientPackageName()) |
| 354 | .build()); |
| 355 | mRouteIdToSessionId.put(routeId, sessionId); |
| 356 | |
Hyundo Moon | f829e6f | 2020-01-11 19:31:35 +0900 | [diff] [blame] | 357 | RoutingSessionInfo newSessionInfo = new RoutingSessionInfo.Builder(sessionInfo) |
Kyunglyul Hyun | 24cc66f | 2019-12-19 19:04:20 +0900 | [diff] [blame] | 358 | .clearSelectedRoutes() |
| 359 | .addSelectedRoute(routeId) |
Hyundo Moon | 0a92657 | 2019-12-28 15:01:21 +0900 | [diff] [blame] | 360 | .removeDeselectableRoute(routeId) |
Kyunglyul Hyun | 6e0c08b | 2020-02-14 15:44:18 +0900 | [diff] [blame] | 361 | .removeTransferableRoute(routeId) |
Kyunglyul Hyun | 24cc66f | 2019-12-19 19:04:20 +0900 | [diff] [blame] | 362 | .build(); |
Hyundo Moon | 6e30f1b | 2020-01-13 19:50:27 +0900 | [diff] [blame] | 363 | notifySessionUpdated(newSessionInfo); |
Kyunglyul Hyun | c658383 | 2020-01-17 11:11:46 +0000 | [diff] [blame] | 364 | publishRoutes(); |
Kyunglyul Hyun | 24cc66f | 2019-12-19 19:04:20 +0900 | [diff] [blame] | 365 | } |
| 366 | |
Hyundo Moon | 9be3548 | 2019-12-30 17:33:13 +0900 | [diff] [blame] | 367 | void maybeDeselectRoute(String routeId) { |
Hyundo Moon | f829e6f | 2020-01-11 19:31:35 +0900 | [diff] [blame] | 368 | if (!mRouteIdToSessionId.containsKey(routeId)) { |
Kyunglyul Hyun | cb8894d | 2019-12-27 14:24:46 +0900 | [diff] [blame] | 369 | return; |
| 370 | } |
| 371 | |
Hyundo Moon | f829e6f | 2020-01-11 19:31:35 +0900 | [diff] [blame] | 372 | String sessionId = mRouteIdToSessionId.get(routeId); |
Hyundo Moon | 0fa60e8 | 2020-02-14 11:44:45 +0900 | [diff] [blame] | 373 | onDeselectRoute(REQUEST_ID_NONE, sessionId, routeId); |
Kyunglyul Hyun | cb8894d | 2019-12-27 14:24:46 +0900 | [diff] [blame] | 374 | } |
| 375 | |
Kyunglyul Hyun | 3aedf02 | 2019-04-15 16:38:19 +0900 | [diff] [blame] | 376 | void publishRoutes() { |
Kyunglyul Hyun | 616096e | 2020-01-09 16:15:03 +0900 | [diff] [blame] | 377 | notifyRoutes(mRoutes.values()); |
Kyunglyul Hyun | d51666d | 2019-04-11 04:08:40 +0000 | [diff] [blame] | 378 | } |
Hyundo Moon | 0fa60e8 | 2020-02-14 11:44:45 +0900 | [diff] [blame] | 379 | |
| 380 | public void setProxy(@Nullable Proxy proxy) { |
| 381 | mProxy = proxy; |
| 382 | } |
| 383 | |
Kyunglyul Hyun | 6a2f1d6 | 2020-05-19 23:00:17 +0900 | [diff] [blame] | 384 | public void setSpy(@Nullable Spy spy) { |
| 385 | mSpy = spy; |
| 386 | } |
| 387 | |
| 388 | /** |
| 389 | * It overrides the original service |
| 390 | */ |
Hyundo Moon | 0fa60e8 | 2020-02-14 11:44:45 +0900 | [diff] [blame] | 391 | public static class Proxy { |
| 392 | public void onSetRouteVolume(String routeId, int volume, long requestId) {} |
| 393 | } |
Kyunglyul Hyun | 6a2f1d6 | 2020-05-19 23:00:17 +0900 | [diff] [blame] | 394 | |
| 395 | /** |
| 396 | * It gets notified but doesn't prevent the original methods to be called. |
| 397 | */ |
| 398 | public static class Spy { |
| 399 | public void onReleaseSession(long requestId, String sessionId) {} |
| 400 | } |
Kyunglyul Hyun | d51666d | 2019-04-11 04:08:40 +0000 | [diff] [blame] | 401 | } |