blob: 97614619653e53ed6182182369bee92c05d0c2db [file] [log] [blame]
Kyunglyul Hyund51666d2019-04-11 04:08:40 +00001/*
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
17package com.android.server.media;
18
Kyunglyul Hyun6c5d7dc2019-04-24 15:57:07 +090019import android.annotation.NonNull;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000020import android.content.ComponentName;
21import android.content.Context;
22import android.content.Intent;
23import android.content.ServiceConnection;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000024import android.media.IMediaRoute2Provider;
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +090025import android.media.IMediaRoute2ProviderClient;
26import android.media.MediaRoute2ProviderInfo;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000027import android.media.MediaRoute2ProviderService;
Hyundo Moonf829e6f2020-01-11 19:31:35 +090028import android.media.RoutingSessionInfo;
Hyundo Moon84e027d2020-01-16 17:39:05 +090029import android.os.Bundle;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000030import android.os.Handler;
31import android.os.IBinder;
32import android.os.IBinder.DeathRecipient;
33import android.os.RemoteException;
34import android.os.UserHandle;
35import android.util.Log;
36import android.util.Slog;
37
38import java.io.PrintWriter;
39import java.lang.ref.WeakReference;
Kyunglyul Hyun6c5d7dc2019-04-24 15:57:07 +090040import java.util.Objects;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000041
42/**
43 * Maintains a connection to a particular media route provider service.
44 */
Kyunglyul Hyun0332e9a22019-11-20 01:39:25 +000045final class MediaRoute2ProviderProxy extends MediaRoute2Provider implements ServiceConnection {
Hyundo Moon7d3ab332019-10-16 11:09:56 +090046 private static final String TAG = "MR2ProviderProxy";
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000047 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
48
49 private final Context mContext;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000050 private final int mUserId;
51 private final Handler mHandler;
52
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000053 // Connection state
54 private boolean mRunning;
55 private boolean mBound;
56 private Connection mActiveConnection;
57 private boolean mConnectionReady;
58
Kyunglyul Hyun6c5d7dc2019-04-24 15:57:07 +090059 MediaRoute2ProviderProxy(@NonNull Context context, @NonNull ComponentName componentName,
60 int userId) {
Kyunglyul Hyun0332e9a22019-11-20 01:39:25 +000061 super(componentName);
Kyunglyul Hyun6c5d7dc2019-04-24 15:57:07 +090062 mContext = Objects.requireNonNull(context, "Context must not be null.");
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000063 mUserId = userId;
64 mHandler = new Handler();
65 }
66
67 public void dump(PrintWriter pw, String prefix) {
68 pw.println(prefix + "Proxy");
69 pw.println(prefix + " mUserId=" + mUserId);
70 pw.println(prefix + " mRunning=" + mRunning);
71 pw.println(prefix + " mBound=" + mBound);
72 pw.println(prefix + " mActiveConnection=" + mActiveConnection);
73 pw.println(prefix + " mConnectionReady=" + mConnectionReady);
74 }
75
Kyunglyul Hyun0332e9a22019-11-20 01:39:25 +000076 @Override
Hyundo Moon84e027d2020-01-16 17:39:05 +090077 public void requestCreateSession(String packageName, String routeId, long requestId,
78 Bundle sessionHints) {
Hyundo Moon63a05402019-12-19 20:13:56 +090079 if (mConnectionReady) {
Hyundo Moon84e027d2020-01-16 17:39:05 +090080 mActiveConnection.requestCreateSession(
81 packageName, routeId, requestId, sessionHints);
Hyundo Moon63a05402019-12-19 20:13:56 +090082 updateBinding();
83 }
84 }
85
86 @Override
Hyundo Moonb26c4b22020-01-08 19:44:43 +090087 public void releaseSession(String sessionId) {
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000088 if (mConnectionReady) {
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +090089 mActiveConnection.releaseSession(sessionId);
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +090090 updateBinding();
91 }
92 }
93
Kyunglyul Hyun0332e9a22019-11-20 01:39:25 +000094 @Override
Hyundo Moonb26c4b22020-01-08 19:44:43 +090095 public void selectRoute(String sessionId, String routeId) {
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +090096 if (mConnectionReady) {
Hyundo Moonb7dc0822020-01-07 16:49:31 +090097 mActiveConnection.selectRoute(sessionId, routeId);
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +090098 }
99 }
100
101 @Override
Hyundo Moonb26c4b22020-01-08 19:44:43 +0900102 public void deselectRoute(String sessionId, String routeId) {
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900103 if (mConnectionReady) {
Hyundo Moonb7dc0822020-01-07 16:49:31 +0900104 mActiveConnection.deselectRoute(sessionId, routeId);
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900105 }
106 }
107
108 @Override
Hyundo Moonb26c4b22020-01-08 19:44:43 +0900109 public void transferToRoute(String sessionId, String routeId) {
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900110 if (mConnectionReady) {
Hyundo Moonb7dc0822020-01-07 16:49:31 +0900111 mActiveConnection.transferToRoute(sessionId, routeId);
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000112 }
113 }
114
Kyunglyul Hyun0332e9a22019-11-20 01:39:25 +0000115 @Override
Hyundo Moonb7dc0822020-01-07 16:49:31 +0900116 public void sendControlRequest(String routeId, Intent request) {
Kyunglyul Hyuncaae8dc2019-04-29 15:45:23 +0900117 if (mConnectionReady) {
Hyundo Moonb7dc0822020-01-07 16:49:31 +0900118 mActiveConnection.sendControlRequest(routeId, request);
Kyunglyul Hyuncaae8dc2019-04-29 15:45:23 +0900119 updateBinding();
120 }
121 }
122
Kyunglyul Hyun0332e9a22019-11-20 01:39:25 +0000123 @Override
Hyundo Moonb7dc0822020-01-07 16:49:31 +0900124 public void requestSetVolume(String routeId, int volume) {
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900125 if (mConnectionReady) {
Hyundo Moonb7dc0822020-01-07 16:49:31 +0900126 mActiveConnection.requestSetVolume(routeId, volume);
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900127 updateBinding();
128 }
129 }
130
Kyunglyul Hyun0332e9a22019-11-20 01:39:25 +0000131 @Override
Hyundo Moonb7dc0822020-01-07 16:49:31 +0900132 public void requestUpdateVolume(String routeId, int delta) {
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900133 if (mConnectionReady) {
Hyundo Moonb7dc0822020-01-07 16:49:31 +0900134 mActiveConnection.requestUpdateVolume(routeId, delta);
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900135 updateBinding();
136 }
137 }
138
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000139 public boolean hasComponentName(String packageName, String className) {
140 return mComponentName.getPackageName().equals(packageName)
141 && mComponentName.getClassName().equals(className);
142 }
143
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000144 public void start() {
145 if (!mRunning) {
146 if (DEBUG) {
147 Slog.d(TAG, this + ": Starting");
148 }
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000149 mRunning = true;
150 updateBinding();
151 }
152 }
153
154 public void stop() {
155 if (mRunning) {
156 if (DEBUG) {
157 Slog.d(TAG, this + ": Stopping");
158 }
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000159 mRunning = false;
160 updateBinding();
161 }
162 }
163
164 public void rebindIfDisconnected() {
165 if (mActiveConnection == null && shouldBind()) {
166 unbind();
167 bind();
168 }
169 }
170
171 private void updateBinding() {
172 if (shouldBind()) {
173 bind();
174 } else {
175 unbind();
176 }
177 }
178
179 private boolean shouldBind() {
Kyunglyul Hyun6c5d7dc2019-04-24 15:57:07 +0900180 //TODO: Binding could be delayed until it's necessary.
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000181 if (mRunning) {
182 return true;
183 }
184 return false;
185 }
186
187 private void bind() {
188 if (!mBound) {
189 if (DEBUG) {
190 Slog.d(TAG, this + ": Binding");
191 }
192
193 Intent service = new Intent(MediaRoute2ProviderService.SERVICE_INTERFACE);
194 service.setComponent(mComponentName);
195 try {
196 mBound = mContext.bindServiceAsUser(service, this,
197 Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
198 new UserHandle(mUserId));
199 if (!mBound && DEBUG) {
200 Slog.d(TAG, this + ": Bind failed");
201 }
202 } catch (SecurityException ex) {
203 if (DEBUG) {
204 Slog.d(TAG, this + ": Bind failed", ex);
205 }
206 }
207 }
208 }
209
210 private void unbind() {
211 if (mBound) {
212 if (DEBUG) {
213 Slog.d(TAG, this + ": Unbinding");
214 }
215
216 mBound = false;
217 disconnect();
218 mContext.unbindService(this);
219 }
220 }
221
222 @Override
223 public void onServiceConnected(ComponentName name, IBinder service) {
224 if (DEBUG) {
225 Slog.d(TAG, this + ": Connected");
226 }
227
228 if (mBound) {
229 disconnect();
230
231 IMediaRoute2Provider provider = IMediaRoute2Provider.Stub.asInterface(service);
232 if (provider != null) {
233 Connection connection = new Connection(provider);
234 if (connection.register()) {
235 mActiveConnection = connection;
236 } else {
237 if (DEBUG) {
238 Slog.d(TAG, this + ": Registration failed");
239 }
240 }
241 } else {
242 Slog.e(TAG, this + ": Service returned invalid remote display provider binder");
243 }
244 }
245 }
246
247 @Override
248 public void onServiceDisconnected(ComponentName name) {
249 if (DEBUG) {
250 Slog.d(TAG, this + ": Service disconnected");
251 }
252 disconnect();
253 }
254
255 private void onConnectionReady(Connection connection) {
256 if (mActiveConnection == connection) {
257 mConnectionReady = true;
258 }
259 }
260
261 private void onConnectionDied(Connection connection) {
262 if (mActiveConnection == connection) {
263 if (DEBUG) {
264 Slog.d(TAG, this + ": Service connection died");
265 }
266 disconnect();
267 }
268 }
269
Kyunglyul Hyunefe43742019-12-31 18:32:28 +0900270 private void onProviderStateUpdated(Connection connection,
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900271 MediaRoute2ProviderInfo providerInfo) {
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +0900272 if (mActiveConnection != connection) {
273 return;
274 }
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +0900275 if (DEBUG) {
276 Slog.d(TAG, this + ": State changed ");
277 }
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900278 setAndNotifyProviderState(providerInfo);
Kyunglyul Hyun23b3aaa2019-08-06 11:17:16 +0900279 }
280
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900281 private void onSessionCreated(Connection connection, RoutingSessionInfo sessionInfo,
Kyunglyul Hyunc7847242019-12-30 17:46:04 +0900282 long requestId) {
Hyundo Moon63a05402019-12-19 20:13:56 +0900283 if (mActiveConnection != connection) {
284 return;
285 }
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900286
287 if (sessionInfo == null) {
288 Slog.w(TAG, "onSessionCreated: Ignoring null sessionInfo sent from " + mComponentName);
289 return;
Kyunglyul Hyun138246e2020-01-02 18:19:52 +0900290 }
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900291
292 sessionInfo = new RoutingSessionInfo.Builder(sessionInfo)
293 .setProviderId(getUniqueId())
294 .build();
295
296 boolean duplicateSessionAlreadyExists = false;
297 synchronized (mLock) {
298 for (int i = 0; i < mSessionInfos.size(); i++) {
299 if (mSessionInfos.get(i).getId().equals(sessionInfo.getId())) {
300 duplicateSessionAlreadyExists = true;
301 break;
302 }
303 }
304 mSessionInfos.add(sessionInfo);
305 }
306
307 if (duplicateSessionAlreadyExists) {
308 Slog.w(TAG, "onSessionCreated: Duplicate session already exists. Ignoring.");
309 return;
310 }
311
Kyunglyul Hyune6b62382019-12-24 11:17:24 +0900312 mCallback.onSessionCreated(this, sessionInfo, requestId);
Hyundo Moon63a05402019-12-19 20:13:56 +0900313 }
314
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900315 private void onSessionCreationFailed(Connection connection, long requestId) {
316 if (mActiveConnection != connection) {
317 return;
318 }
319
320 if (requestId == MediaRoute2ProviderService.REQUEST_ID_UNKNOWN) {
321 Slog.w(TAG, "onSessionCreationFailed: Ignoring requestId REQUEST_ID_UNKNOWN");
322 return;
323 }
324
325 mCallback.onSessionCreationFailed(this, requestId);
326 }
327
328 private void onSessionUpdated(Connection connection, RoutingSessionInfo sessionInfo) {
Hyundo Moon0a926572019-12-28 15:01:21 +0900329 if (mActiveConnection != connection) {
330 return;
331 }
332 if (sessionInfo == null) {
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900333 Slog.w(TAG, "onSessionUpdated: Ignoring null sessionInfo sent from "
Hyundo Moon0a926572019-12-28 15:01:21 +0900334 + mComponentName);
335 return;
336 }
Hyundo Moonb26c4b22020-01-08 19:44:43 +0900337
Hyundo Moonf829e6f2020-01-11 19:31:35 +0900338 sessionInfo = new RoutingSessionInfo.Builder(sessionInfo)
Hyundo Moonb26c4b22020-01-08 19:44:43 +0900339 .setProviderId(getUniqueId())
340 .build();
341
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900342 boolean found = false;
343 synchronized (mLock) {
344 for (int i = 0; i < mSessionInfos.size(); i++) {
345 if (mSessionInfos.get(i).getId().equals(sessionInfo.getId())) {
346 mSessionInfos.set(i, sessionInfo);
347 found = true;
348 break;
349 }
350 }
351 }
352
353 if (!found) {
354 Slog.w(TAG, "onSessionUpdated: Matching session info not found");
355 return;
356 }
357
358 mCallback.onSessionUpdated(this, sessionInfo);
359 }
360
361 private void onSessionReleased(Connection connection, RoutingSessionInfo sessionInfo) {
362 if (mActiveConnection != connection) {
363 return;
364 }
365 if (sessionInfo == null) {
366 Slog.w(TAG, "onSessionReleased: Ignoring null sessionInfo sent from " + mComponentName);
367 return;
368 }
369
370 sessionInfo = new RoutingSessionInfo.Builder(sessionInfo)
371 .setProviderId(getUniqueId())
372 .build();
373
374 boolean found = false;
375 synchronized (mLock) {
376 for (int i = 0; i < mSessionInfos.size(); i++) {
377 if (mSessionInfos.get(i).getId().equals(sessionInfo.getId())) {
378 mSessionInfos.remove(i);
379 found = true;
380 break;
381 }
382 }
383 }
384
385 if (!found) {
386 Slog.w(TAG, "onSessionReleased: Matching session info not found");
387 return;
388 }
389
390 mCallback.onSessionReleased(this, sessionInfo);
Hyundo Moon0a926572019-12-28 15:01:21 +0900391 }
392
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000393 private void disconnect() {
394 if (mActiveConnection != null) {
395 mConnectionReady = false;
396 mActiveConnection.dispose();
397 mActiveConnection = null;
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900398 setAndNotifyProviderState(null);
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000399 }
400 }
401
402 @Override
403 public String toString() {
404 return "Service connection " + mComponentName.flattenToShortString();
405 }
406
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000407 private final class Connection implements DeathRecipient {
408 private final IMediaRoute2Provider mProvider;
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +0900409 private final ProviderClient mClient;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000410
411 Connection(IMediaRoute2Provider provider) {
412 mProvider = provider;
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +0900413 mClient = new ProviderClient(this);
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000414 }
415
416 public boolean register() {
417 try {
418 mProvider.asBinder().linkToDeath(this, 0);
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +0900419 mProvider.setClient(mClient);
420 mHandler.post(() -> onConnectionReady(Connection.this));
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000421 return true;
422 } catch (RemoteException ex) {
423 binderDied();
424 }
425 return false;
426 }
427
428 public void dispose() {
429 mProvider.asBinder().unlinkToDeath(this, 0);
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +0900430 mClient.dispose();
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000431 }
432
Hyundo Moon84e027d2020-01-16 17:39:05 +0900433 public void requestCreateSession(String packageName, String routeId, long requestId,
434 Bundle sessionHints) {
Hyundo Moon63a05402019-12-19 20:13:56 +0900435 try {
Hyundo Moon84e027d2020-01-16 17:39:05 +0900436 mProvider.requestCreateSession(packageName, routeId, requestId, sessionHints);
Hyundo Moon63a05402019-12-19 20:13:56 +0900437 } catch (RemoteException ex) {
438 Slog.e(TAG, "Failed to deliver request to create a session.", ex);
439 }
440 }
441
Hyundo Moonb26c4b22020-01-08 19:44:43 +0900442 public void releaseSession(String sessionId) {
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000443 try {
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900444 mProvider.releaseSession(sessionId);
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000445 } catch (RemoteException ex) {
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900446 Slog.e(TAG, "Failed to deliver request to release a session.", ex);
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000447 }
448 }
449
Hyundo Moonb26c4b22020-01-08 19:44:43 +0900450 public void selectRoute(String sessionId, String routeId) {
Kyunglyul Hyuncaae8dc2019-04-29 15:45:23 +0900451 try {
Hyundo Moon9be35482019-12-30 17:33:13 +0900452 mProvider.selectRoute(sessionId, routeId);
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +0900453 } catch (RemoteException ex) {
Hyundo Moon9be35482019-12-30 17:33:13 +0900454 Slog.e(TAG, "Failed to deliver request to select a route for a session.", ex);
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900455 }
456 }
457
Hyundo Moonb26c4b22020-01-08 19:44:43 +0900458 public void deselectRoute(String sessionId, String routeId) {
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900459 try {
Hyundo Moon9be35482019-12-30 17:33:13 +0900460 mProvider.deselectRoute(sessionId, routeId);
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900461 } catch (RemoteException ex) {
Hyundo Moon9be35482019-12-30 17:33:13 +0900462 Slog.e(TAG, "Failed to deliver request to deselect a route from a session.", ex);
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900463 }
464 }
465
Hyundo Moonb26c4b22020-01-08 19:44:43 +0900466 public void transferToRoute(String sessionId, String routeId) {
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900467 try {
Hyundo Moon0a926572019-12-28 15:01:21 +0900468 mProvider.transferToRoute(sessionId, routeId);
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900469 } catch (RemoteException ex) {
470 Slog.e(TAG, "Failed to deliver request to transfer a session to a route.", ex);
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +0900471 }
472 }
473
474 public void sendControlRequest(String routeId, Intent request) {
475 try {
476 mProvider.notifyControlRequestSent(routeId, request);
Kyunglyul Hyuncaae8dc2019-04-29 15:45:23 +0900477 } catch (RemoteException ex) {
478 Slog.e(TAG, "Failed to deliver request to send control request.", ex);
479 }
480 }
481
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900482 public void requestSetVolume(String routeId, int volume) {
483 try {
484 mProvider.requestSetVolume(routeId, volume);
485 } catch (RemoteException ex) {
486 Slog.e(TAG, "Failed to deliver request to request set volume.", ex);
487 }
488 }
489
490 public void requestUpdateVolume(String routeId, int delta) {
491 try {
492 mProvider.requestUpdateVolume(routeId, delta);
493 } catch (RemoteException ex) {
494 Slog.e(TAG, "Failed to deliver request to request update volume.", ex);
495 }
496 }
497
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000498 @Override
499 public void binderDied() {
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +0900500 mHandler.post(() -> onConnectionDied(Connection.this));
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000501 }
502
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900503 void postProviderStateUpdated(MediaRoute2ProviderInfo providerInfo) {
504 mHandler.post(() -> onProviderStateUpdated(Connection.this, providerInfo));
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000505 }
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900506
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900507 void postSessionCreated(RoutingSessionInfo sessionInfo, long requestId) {
508 mHandler.post(() -> onSessionCreated(Connection.this, sessionInfo, requestId));
Hyundo Moon63a05402019-12-19 20:13:56 +0900509 }
Hyundo Moon0a926572019-12-28 15:01:21 +0900510
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900511 void postSessionCreationFailed(long requestId) {
512 mHandler.post(() -> onSessionCreationFailed(Connection.this, requestId));
513 }
514
515 void postSessionUpdated(RoutingSessionInfo sessionInfo) {
516 mHandler.post(() -> onSessionUpdated(Connection.this, sessionInfo));
517 }
518
519 void postSessionReleased(RoutingSessionInfo sessionInfo) {
520 mHandler.post(() -> onSessionReleased(Connection.this, sessionInfo));
Hyundo Moon0a926572019-12-28 15:01:21 +0900521 }
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000522 }
523
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +0900524 private static final class ProviderClient extends IMediaRoute2ProviderClient.Stub {
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000525 private final WeakReference<Connection> mConnectionRef;
526
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +0900527 ProviderClient(Connection connection) {
528 mConnectionRef = new WeakReference<>(connection);
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000529 }
530
531 public void dispose() {
532 mConnectionRef.clear();
533 }
534
535 @Override
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900536 public void updateState(MediaRoute2ProviderInfo providerInfo) {
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +0900537 Connection connection = mConnectionRef.get();
538 if (connection != null) {
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900539 connection.postProviderStateUpdated(providerInfo);
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +0900540 }
541 }
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900542
543 @Override
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900544 public void notifySessionCreated(RoutingSessionInfo sessionInfo, long requestId) {
Hyundo Moon63a05402019-12-19 20:13:56 +0900545 Connection connection = mConnectionRef.get();
546 if (connection != null) {
Kyunglyul Hyune6b62382019-12-24 11:17:24 +0900547 connection.postSessionCreated(sessionInfo, requestId);
Hyundo Moon63a05402019-12-19 20:13:56 +0900548 }
549 }
Hyundo Moon0a926572019-12-28 15:01:21 +0900550
551 @Override
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900552 public void notifySessionCreationFailed(long requestId) {
Hyundo Moon0a926572019-12-28 15:01:21 +0900553 Connection connection = mConnectionRef.get();
554 if (connection != null) {
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900555 connection.postSessionCreationFailed(requestId);
556 }
557 }
558
559 @Override
560 public void notifySessionUpdated(RoutingSessionInfo sessionInfo) {
561 Connection connection = mConnectionRef.get();
562 if (connection != null) {
563 connection.postSessionUpdated(sessionInfo);
564 }
565 }
566
567 @Override
568 public void notifySessionReleased(RoutingSessionInfo sessionInfo) {
569 Connection connection = mConnectionRef.get();
570 if (connection != null) {
571 connection.postSessionReleased(sessionInfo);
Hyundo Moon0a926572019-12-28 15:01:21 +0900572 }
573 }
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000574 }
575}