blob: d6b98e2de901813f4fd79c2778aa475c3f6735c0 [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;
Hyundo Moon56337492020-02-16 16:19:54 +090024import android.media.IMediaRoute2ProviderService;
25import android.media.IMediaRoute2ProviderServiceCallback;
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +090026import android.media.MediaRoute2ProviderInfo;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000027import android.media.MediaRoute2ProviderService;
Kyunglyul Hyun1866d8a2020-01-31 11:56:34 +090028import android.media.RouteDiscoveryPreference;
Hyundo Moonf829e6f2020-01-11 19:31:35 +090029import android.media.RoutingSessionInfo;
Hyundo Moon84e027d2020-01-16 17:39:05 +090030import android.os.Bundle;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000031import android.os.Handler;
32import android.os.IBinder;
33import android.os.IBinder.DeathRecipient;
Hyundo Moon56337492020-02-16 16:19:54 +090034import android.os.Looper;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000035import android.os.RemoteException;
36import android.os.UserHandle;
37import android.util.Log;
38import android.util.Slog;
39
40import java.io.PrintWriter;
41import java.lang.ref.WeakReference;
Kyunglyul Hyun6c5d7dc2019-04-24 15:57:07 +090042import java.util.Objects;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000043
44/**
Hyundo Moon56337492020-02-16 16:19:54 +090045 * Maintains a connection to a particular {@link MediaRoute2ProviderService}.
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000046 */
Hyundo Moon56337492020-02-16 16:19:54 +090047final class MediaRoute2ProviderServiceProxy extends MediaRoute2Provider
48 implements ServiceConnection {
49 private static final String TAG = "MR2ProviderSvcProxy";
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000050 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
51
52 private final Context mContext;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000053 private final int mUserId;
54 private final Handler mHandler;
55
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000056 // Connection state
57 private boolean mRunning;
58 private boolean mBound;
59 private Connection mActiveConnection;
60 private boolean mConnectionReady;
61
Kyunglyul Hyunf2b19c8b2020-05-18 18:29:11 +090062 private RouteDiscoveryPreference mLastDiscoveryPreference = null;
Kyunglyul Hyunbab0cda2020-03-10 20:59:49 +090063
Hyundo Moon56337492020-02-16 16:19:54 +090064 MediaRoute2ProviderServiceProxy(@NonNull Context context, @NonNull ComponentName componentName,
Kyunglyul Hyun6c5d7dc2019-04-24 15:57:07 +090065 int userId) {
Kyunglyul Hyun0332e9a22019-11-20 01:39:25 +000066 super(componentName);
Kyunglyul Hyun6c5d7dc2019-04-24 15:57:07 +090067 mContext = Objects.requireNonNull(context, "Context must not be null.");
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000068 mUserId = userId;
Hyundo Moon56337492020-02-16 16:19:54 +090069 mHandler = new Handler(Looper.myLooper());
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000070 }
71
72 public void dump(PrintWriter pw, String prefix) {
73 pw.println(prefix + "Proxy");
74 pw.println(prefix + " mUserId=" + mUserId);
75 pw.println(prefix + " mRunning=" + mRunning);
76 pw.println(prefix + " mBound=" + mBound);
77 pw.println(prefix + " mActiveConnection=" + mActiveConnection);
78 pw.println(prefix + " mConnectionReady=" + mConnectionReady);
79 }
80
Kyunglyul Hyun0332e9a22019-11-20 01:39:25 +000081 @Override
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +090082 public void requestCreateSession(long requestId, String packageName, String routeId,
Hyundo Moon84e027d2020-01-16 17:39:05 +090083 Bundle sessionHints) {
Hyundo Moon63a05402019-12-19 20:13:56 +090084 if (mConnectionReady) {
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +090085 mActiveConnection.requestCreateSession(requestId, packageName, routeId, sessionHints);
Hyundo Moon63a05402019-12-19 20:13:56 +090086 updateBinding();
87 }
88 }
89
90 @Override
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +090091 public void releaseSession(long requestId, String sessionId) {
Kyunglyul Hyund51666d2019-04-11 04:08:40 +000092 if (mConnectionReady) {
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +090093 mActiveConnection.releaseSession(requestId, sessionId);
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +090094 updateBinding();
95 }
96 }
97
Kyunglyul Hyun0332e9a22019-11-20 01:39:25 +000098 @Override
Kyunglyul Hyun1866d8a2020-01-31 11:56:34 +090099 public void updateDiscoveryPreference(RouteDiscoveryPreference discoveryPreference) {
Kyunglyul Hyunf2b19c8b2020-05-18 18:29:11 +0900100 mLastDiscoveryPreference = discoveryPreference;
Kyunglyul Hyun1866d8a2020-01-31 11:56:34 +0900101 if (mConnectionReady) {
102 mActiveConnection.updateDiscoveryPreference(discoveryPreference);
103 updateBinding();
104 }
105 }
106
107 @Override
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900108 public void selectRoute(long requestId, String sessionId, String routeId) {
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +0900109 if (mConnectionReady) {
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900110 mActiveConnection.selectRoute(requestId, sessionId, routeId);
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900111 }
112 }
113
114 @Override
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900115 public void deselectRoute(long requestId, String sessionId, String routeId) {
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900116 if (mConnectionReady) {
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900117 mActiveConnection.deselectRoute(requestId, sessionId, routeId);
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900118 }
119 }
120
121 @Override
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900122 public void transferToRoute(long requestId, String sessionId, String routeId) {
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900123 if (mConnectionReady) {
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900124 mActiveConnection.transferToRoute(requestId, sessionId, routeId);
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000125 }
126 }
127
Kyunglyul Hyun0332e9a22019-11-20 01:39:25 +0000128 @Override
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900129 public void setRouteVolume(long requestId, String routeId, int volume) {
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900130 if (mConnectionReady) {
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900131 mActiveConnection.setRouteVolume(requestId, routeId, volume);
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900132 updateBinding();
133 }
134 }
135
136 @Override
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900137 public void setSessionVolume(long requestId, String sessionId, int volume) {
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900138 if (mConnectionReady) {
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900139 mActiveConnection.setSessionVolume(requestId, sessionId, volume);
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900140 updateBinding();
141 }
142 }
143
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000144 public boolean hasComponentName(String packageName, String className) {
145 return mComponentName.getPackageName().equals(packageName)
146 && mComponentName.getClassName().equals(className);
147 }
148
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000149 public void start() {
150 if (!mRunning) {
151 if (DEBUG) {
152 Slog.d(TAG, this + ": Starting");
153 }
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000154 mRunning = true;
155 updateBinding();
156 }
157 }
158
159 public void stop() {
160 if (mRunning) {
161 if (DEBUG) {
162 Slog.d(TAG, this + ": Stopping");
163 }
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000164 mRunning = false;
165 updateBinding();
166 }
167 }
168
169 public void rebindIfDisconnected() {
Kyunglyul Hyun89e2ee92020-04-10 20:17:04 +0900170 //TODO: When we are connecting to the service, calling this will unbind and bind again.
171 // We'd better not unbind if we are connecting.
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000172 if (mActiveConnection == null && shouldBind()) {
173 unbind();
174 bind();
175 }
176 }
177
178 private void updateBinding() {
179 if (shouldBind()) {
180 bind();
181 } else {
182 unbind();
183 }
184 }
185
186 private boolean shouldBind() {
Kyunglyul Hyun6c5d7dc2019-04-24 15:57:07 +0900187 //TODO: Binding could be delayed until it's necessary.
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000188 if (mRunning) {
189 return true;
190 }
191 return false;
192 }
193
194 private void bind() {
195 if (!mBound) {
196 if (DEBUG) {
197 Slog.d(TAG, this + ": Binding");
198 }
199
200 Intent service = new Intent(MediaRoute2ProviderService.SERVICE_INTERFACE);
201 service.setComponent(mComponentName);
202 try {
203 mBound = mContext.bindServiceAsUser(service, this,
204 Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
205 new UserHandle(mUserId));
206 if (!mBound && DEBUG) {
207 Slog.d(TAG, this + ": Bind failed");
208 }
209 } catch (SecurityException ex) {
210 if (DEBUG) {
211 Slog.d(TAG, this + ": Bind failed", ex);
212 }
213 }
214 }
215 }
216
217 private void unbind() {
218 if (mBound) {
219 if (DEBUG) {
220 Slog.d(TAG, this + ": Unbinding");
221 }
222
223 mBound = false;
224 disconnect();
225 mContext.unbindService(this);
226 }
227 }
228
229 @Override
230 public void onServiceConnected(ComponentName name, IBinder service) {
231 if (DEBUG) {
232 Slog.d(TAG, this + ": Connected");
233 }
234
235 if (mBound) {
236 disconnect();
Hyundo Moon56337492020-02-16 16:19:54 +0900237 IMediaRoute2ProviderService serviceBinder =
238 IMediaRoute2ProviderService.Stub.asInterface(service);
239 if (serviceBinder != null) {
240 Connection connection = new Connection(serviceBinder);
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000241 if (connection.register()) {
242 mActiveConnection = connection;
243 } else {
244 if (DEBUG) {
245 Slog.d(TAG, this + ": Registration failed");
246 }
247 }
248 } else {
Hyundo Moon56337492020-02-16 16:19:54 +0900249 Slog.e(TAG, this + ": Service returned invalid binder");
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000250 }
251 }
252 }
253
254 @Override
255 public void onServiceDisconnected(ComponentName name) {
256 if (DEBUG) {
257 Slog.d(TAG, this + ": Service disconnected");
258 }
259 disconnect();
260 }
261
Hyundo Moon7294e5f2020-01-29 13:26:14 +0900262 @Override
263 public void onBindingDied(ComponentName name) {
264 if (DEBUG) {
265 Slog.d(TAG, this + ": Service binding died");
266 }
Hyundo Moon7294e5f2020-01-29 13:26:14 +0900267 if (shouldBind()) {
268 unbind();
269 bind();
270 }
271 }
272
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000273 private void onConnectionReady(Connection connection) {
274 if (mActiveConnection == connection) {
275 mConnectionReady = true;
Kyunglyul Hyunf2b19c8b2020-05-18 18:29:11 +0900276 if (mLastDiscoveryPreference != null) {
277 updateDiscoveryPreference(mLastDiscoveryPreference);
Kyunglyul Hyunbab0cda2020-03-10 20:59:49 +0900278 }
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000279 }
280 }
281
282 private void onConnectionDied(Connection connection) {
283 if (mActiveConnection == connection) {
284 if (DEBUG) {
285 Slog.d(TAG, this + ": Service connection died");
286 }
287 disconnect();
288 }
289 }
290
Kyunglyul Hyunefe43742019-12-31 18:32:28 +0900291 private void onProviderStateUpdated(Connection connection,
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900292 MediaRoute2ProviderInfo providerInfo) {
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +0900293 if (mActiveConnection != connection) {
294 return;
295 }
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +0900296 if (DEBUG) {
297 Slog.d(TAG, this + ": State changed ");
298 }
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900299 setAndNotifyProviderState(providerInfo);
Kyunglyul Hyun23b3aaa2019-08-06 11:17:16 +0900300 }
301
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900302 private void onSessionCreated(Connection connection, long requestId,
303 RoutingSessionInfo sessionInfo) {
Hyundo Moon63a05402019-12-19 20:13:56 +0900304 if (mActiveConnection != connection) {
305 return;
306 }
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900307
308 if (sessionInfo == null) {
309 Slog.w(TAG, "onSessionCreated: Ignoring null sessionInfo sent from " + mComponentName);
310 return;
Kyunglyul Hyun138246e2020-01-02 18:19:52 +0900311 }
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900312
Kyunglyul Hyune2dbbf72020-04-29 22:40:59 +0900313 sessionInfo = updateSessionInfo(sessionInfo);
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900314
315 boolean duplicateSessionAlreadyExists = false;
316 synchronized (mLock) {
317 for (int i = 0; i < mSessionInfos.size(); i++) {
318 if (mSessionInfos.get(i).getId().equals(sessionInfo.getId())) {
319 duplicateSessionAlreadyExists = true;
320 break;
321 }
322 }
323 mSessionInfos.add(sessionInfo);
324 }
325
326 if (duplicateSessionAlreadyExists) {
327 Slog.w(TAG, "onSessionCreated: Duplicate session already exists. Ignoring.");
328 return;
329 }
330
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900331 mCallback.onSessionCreated(this, requestId, sessionInfo);
Hyundo Moon63a05402019-12-19 20:13:56 +0900332 }
333
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900334 private void onSessionUpdated(Connection connection, RoutingSessionInfo sessionInfo) {
Hyundo Moon0a926572019-12-28 15:01:21 +0900335 if (mActiveConnection != connection) {
336 return;
337 }
338 if (sessionInfo == null) {
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900339 Slog.w(TAG, "onSessionUpdated: Ignoring null sessionInfo sent from "
Hyundo Moon0a926572019-12-28 15:01:21 +0900340 + mComponentName);
341 return;
342 }
Hyundo Moonb26c4b22020-01-08 19:44:43 +0900343
Kyunglyul Hyune2dbbf72020-04-29 22:40:59 +0900344 sessionInfo = updateSessionInfo(sessionInfo);
Hyundo Moonb26c4b22020-01-08 19:44:43 +0900345
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900346 boolean found = false;
347 synchronized (mLock) {
348 for (int i = 0; i < mSessionInfos.size(); i++) {
349 if (mSessionInfos.get(i).getId().equals(sessionInfo.getId())) {
350 mSessionInfos.set(i, sessionInfo);
351 found = true;
352 break;
353 }
354 }
355 }
356
357 if (!found) {
358 Slog.w(TAG, "onSessionUpdated: Matching session info not found");
359 return;
360 }
361
362 mCallback.onSessionUpdated(this, sessionInfo);
363 }
364
365 private void onSessionReleased(Connection connection, RoutingSessionInfo sessionInfo) {
366 if (mActiveConnection != connection) {
367 return;
368 }
369 if (sessionInfo == null) {
370 Slog.w(TAG, "onSessionReleased: Ignoring null sessionInfo sent from " + mComponentName);
371 return;
372 }
373
Kyunglyul Hyune2dbbf72020-04-29 22:40:59 +0900374 sessionInfo = updateSessionInfo(sessionInfo);
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900375
376 boolean found = false;
377 synchronized (mLock) {
378 for (int i = 0; i < mSessionInfos.size(); i++) {
379 if (mSessionInfos.get(i).getId().equals(sessionInfo.getId())) {
380 mSessionInfos.remove(i);
381 found = true;
382 break;
383 }
384 }
385 }
386
387 if (!found) {
388 Slog.w(TAG, "onSessionReleased: Matching session info not found");
389 return;
390 }
391
392 mCallback.onSessionReleased(this, sessionInfo);
Hyundo Moon0a926572019-12-28 15:01:21 +0900393 }
394
Kyunglyul Hyune2dbbf72020-04-29 22:40:59 +0900395 private RoutingSessionInfo updateSessionInfo(RoutingSessionInfo sessionInfo) {
396 return new RoutingSessionInfo.Builder(sessionInfo)
397 .setOwnerPackageName(mComponentName.getPackageName())
398 .setProviderId(getUniqueId())
399 .build();
400 }
401
Hyundo Moon0fa60e82020-02-14 11:44:45 +0900402 private void onRequestFailed(Connection connection, long requestId, int reason) {
403 if (mActiveConnection != connection) {
404 return;
405 }
406
407 if (requestId == MediaRoute2ProviderService.REQUEST_ID_NONE) {
408 Slog.w(TAG, "onRequestFailed: Ignoring requestId REQUEST_ID_NONE");
409 return;
410 }
411
412 mCallback.onRequestFailed(this, requestId, reason);
413 }
414
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000415 private void disconnect() {
416 if (mActiveConnection != null) {
417 mConnectionReady = false;
418 mActiveConnection.dispose();
419 mActiveConnection = null;
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900420 setAndNotifyProviderState(null);
Kyunglyul Hyun47d289e2020-02-07 19:24:08 +0900421 synchronized (mLock) {
422 for (RoutingSessionInfo sessionInfo : mSessionInfos) {
423 mCallback.onSessionReleased(this, sessionInfo);
424 }
425 mSessionInfos.clear();
426 }
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000427 }
428 }
429
430 @Override
431 public String toString() {
432 return "Service connection " + mComponentName.flattenToShortString();
433 }
434
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000435 private final class Connection implements DeathRecipient {
Hyundo Moon56337492020-02-16 16:19:54 +0900436 private final IMediaRoute2ProviderService mService;
437 private final ServiceCallbackStub mCallbackStub;
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000438
Hyundo Moon56337492020-02-16 16:19:54 +0900439 Connection(IMediaRoute2ProviderService serviceBinder) {
440 mService = serviceBinder;
441 mCallbackStub = new ServiceCallbackStub(this);
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000442 }
443
444 public boolean register() {
445 try {
Hyundo Moon56337492020-02-16 16:19:54 +0900446 mService.asBinder().linkToDeath(this, 0);
447 mService.setCallback(mCallbackStub);
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +0900448 mHandler.post(() -> onConnectionReady(Connection.this));
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000449 return true;
450 } catch (RemoteException ex) {
451 binderDied();
452 }
453 return false;
454 }
455
456 public void dispose() {
Hyundo Moon56337492020-02-16 16:19:54 +0900457 mService.asBinder().unlinkToDeath(this, 0);
458 mCallbackStub.dispose();
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000459 }
460
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900461 public void requestCreateSession(long requestId, String packageName, String routeId,
Hyundo Moon84e027d2020-01-16 17:39:05 +0900462 Bundle sessionHints) {
Hyundo Moon63a05402019-12-19 20:13:56 +0900463 try {
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900464 mService.requestCreateSession(requestId, packageName, routeId, sessionHints);
Hyundo Moon63a05402019-12-19 20:13:56 +0900465 } catch (RemoteException ex) {
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900466 Slog.e(TAG, "requestCreateSession: Failed to deliver request.");
Hyundo Moon63a05402019-12-19 20:13:56 +0900467 }
468 }
469
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900470 public void releaseSession(long requestId, String sessionId) {
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000471 try {
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900472 mService.releaseSession(requestId, sessionId);
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000473 } catch (RemoteException ex) {
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900474 Slog.e(TAG, "releaseSession: Failed to deliver request.");
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000475 }
476 }
477
Kyunglyul Hyun1866d8a2020-01-31 11:56:34 +0900478 public void updateDiscoveryPreference(RouteDiscoveryPreference discoveryPreference) {
479 try {
Hyundo Moon56337492020-02-16 16:19:54 +0900480 mService.updateDiscoveryPreference(discoveryPreference);
Kyunglyul Hyun1866d8a2020-01-31 11:56:34 +0900481 } catch (RemoteException ex) {
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900482 Slog.e(TAG, "updateDiscoveryPreference: Failed to deliver request.");
Kyunglyul Hyun1866d8a2020-01-31 11:56:34 +0900483 }
484 }
485
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900486 public void selectRoute(long requestId, String sessionId, String routeId) {
Kyunglyul Hyuncaae8dc2019-04-29 15:45:23 +0900487 try {
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900488 mService.selectRoute(requestId, sessionId, routeId);
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +0900489 } catch (RemoteException ex) {
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900490 Slog.e(TAG, "selectRoute: Failed to deliver request.", ex);
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900491 }
492 }
493
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900494 public void deselectRoute(long requestId, String sessionId, String routeId) {
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900495 try {
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900496 mService.deselectRoute(requestId, sessionId, routeId);
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900497 } catch (RemoteException ex) {
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900498 Slog.e(TAG, "deselectRoute: Failed to deliver request.", ex);
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900499 }
500 }
501
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900502 public void transferToRoute(long requestId, String sessionId, String routeId) {
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900503 try {
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900504 mService.transferToRoute(requestId, sessionId, routeId);
Kyunglyul Hyuncb8894d2019-12-27 14:24:46 +0900505 } catch (RemoteException ex) {
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900506 Slog.e(TAG, "transferToRoute: Failed to deliver request.", ex);
Kyunglyul Hyuna0d47412019-07-01 11:14:24 +0900507 }
508 }
509
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900510 public void setRouteVolume(long requestId, String routeId, int volume) {
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900511 try {
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900512 mService.setRouteVolume(requestId, routeId, volume);
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900513 } catch (RemoteException ex) {
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900514 Slog.e(TAG, "setRouteVolume: Failed to deliver request.", ex);
515 }
516 }
517
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900518 public void setSessionVolume(long requestId, String sessionId, int volume) {
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900519 try {
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900520 mService.setSessionVolume(requestId, sessionId, volume);
Kyunglyul Hyun5161b372020-02-05 18:45:35 +0900521 } catch (RemoteException ex) {
522 Slog.e(TAG, "setSessionVolume: Failed to deliver request.", ex);
Kyunglyul Hyun5a8dedc2019-10-10 14:09:44 +0900523 }
524 }
525
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000526 @Override
527 public void binderDied() {
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +0900528 mHandler.post(() -> onConnectionDied(Connection.this));
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000529 }
530
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900531 void postProviderStateUpdated(MediaRoute2ProviderInfo providerInfo) {
532 mHandler.post(() -> onProviderStateUpdated(Connection.this, providerInfo));
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000533 }
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900534
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900535 void postSessionCreated(long requestId, RoutingSessionInfo sessionInfo) {
536 mHandler.post(() -> onSessionCreated(Connection.this, requestId, sessionInfo));
Hyundo Moon63a05402019-12-19 20:13:56 +0900537 }
Hyundo Moon0a926572019-12-28 15:01:21 +0900538
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900539 void postSessionUpdated(RoutingSessionInfo sessionInfo) {
540 mHandler.post(() -> onSessionUpdated(Connection.this, sessionInfo));
541 }
542
543 void postSessionReleased(RoutingSessionInfo sessionInfo) {
544 mHandler.post(() -> onSessionReleased(Connection.this, sessionInfo));
Hyundo Moon0a926572019-12-28 15:01:21 +0900545 }
Hyundo Moon0fa60e82020-02-14 11:44:45 +0900546
Hyundo Moon7c2059c2020-02-27 19:01:52 +0900547 void postRequestFailed(long requestId, int reason) {
Hyundo Moon0fa60e82020-02-14 11:44:45 +0900548 mHandler.post(() -> onRequestFailed(Connection.this, requestId, reason));
549 }
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000550 }
551
Hyundo Moon56337492020-02-16 16:19:54 +0900552 private static final class ServiceCallbackStub extends
553 IMediaRoute2ProviderServiceCallback.Stub {
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000554 private final WeakReference<Connection> mConnectionRef;
555
Hyundo Moon56337492020-02-16 16:19:54 +0900556 ServiceCallbackStub(Connection connection) {
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +0900557 mConnectionRef = new WeakReference<>(connection);
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000558 }
559
560 public void dispose() {
561 mConnectionRef.clear();
562 }
563
564 @Override
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900565 public void updateState(MediaRoute2ProviderInfo providerInfo) {
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +0900566 Connection connection = mConnectionRef.get();
567 if (connection != null) {
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900568 connection.postProviderStateUpdated(providerInfo);
Kyunglyul Hyun3aedf022019-04-15 16:38:19 +0900569 }
570 }
Kyunglyul Hyunf7d5e042019-11-11 13:56:28 +0900571
572 @Override
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900573 public void notifySessionCreated(long requestId, RoutingSessionInfo sessionInfo) {
Hyundo Moon63a05402019-12-19 20:13:56 +0900574 Connection connection = mConnectionRef.get();
575 if (connection != null) {
Hyundo Moonf8e49f4b2020-03-06 17:19:42 +0900576 connection.postSessionCreated(requestId, sessionInfo);
Hyundo Moon63a05402019-12-19 20:13:56 +0900577 }
578 }
Hyundo Moon0a926572019-12-28 15:01:21 +0900579
580 @Override
Hyundo Moon6e30f1b2020-01-13 19:50:27 +0900581 public void notifySessionUpdated(RoutingSessionInfo sessionInfo) {
582 Connection connection = mConnectionRef.get();
583 if (connection != null) {
584 connection.postSessionUpdated(sessionInfo);
585 }
586 }
587
588 @Override
589 public void notifySessionReleased(RoutingSessionInfo sessionInfo) {
590 Connection connection = mConnectionRef.get();
591 if (connection != null) {
592 connection.postSessionReleased(sessionInfo);
Hyundo Moon0a926572019-12-28 15:01:21 +0900593 }
594 }
Hyundo Moon0fa60e82020-02-14 11:44:45 +0900595
596 @Override
597 public void notifyRequestFailed(long requestId, int reason) {
598 Connection connection = mConnectionRef.get();
599 if (connection != null) {
Hyundo Moon7c2059c2020-02-27 19:01:52 +0900600 connection.postRequestFailed(requestId, reason);
Hyundo Moon0fa60e82020-02-14 11:44:45 +0900601 }
602 }
Kyunglyul Hyund51666d2019-04-11 04:08:40 +0000603 }
604}