blob: e2087e6ca8225e58f2e754fe532be5099182354a [file] [log] [blame]
RoboErik01fe6612014-02-13 14:19:04 -08001/*
2 * Copyright (C) 2014 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
RoboErike34c09d2014-07-24 10:20:41 -070019import android.app.PendingIntent;
RoboErikef3c9e92014-06-19 16:07:28 -070020import android.content.Context;
RoboErik01fe6612014-02-13 14:19:04 -080021import android.content.Intent;
Hyundo Moonbb07e9b2019-05-09 16:03:51 +090022import android.content.pm.ParceledListSlice;
Jin Seok Parka1385732018-12-07 14:36:14 +090023import android.media.AudioAttributes;
Gabriel Pealf0593bc2014-07-22 09:39:06 -070024import android.media.AudioManager;
RoboErik0dac35a2014-08-12 15:48:49 -070025import android.media.AudioManagerInternal;
RoboErik165809b2014-09-29 14:16:45 -070026import android.media.AudioSystem;
Gabriel Pealf0593bc2014-07-22 09:39:06 -070027import android.media.MediaMetadata;
28import android.media.Rating;
29import android.media.VolumeProvider;
Hyundo Moon24f366b2019-03-15 15:16:00 +090030import android.media.session.ISession;
Hyundo Moon7969f772019-03-21 17:16:16 +090031import android.media.session.ISessionCallback;
Hyundo Moon8b1f9752019-03-14 17:44:29 +090032import android.media.session.ISessionController;
Hyundo Moon4e4459b2019-03-26 19:18:45 +090033import android.media.session.ISessionControllerCallback;
RoboErik42ea7ee2014-05-16 16:27:35 -070034import android.media.session.MediaController;
RoboErikd2b8c942014-08-19 11:23:40 -070035import android.media.session.MediaController.PlaybackInfo;
RoboErik42ea7ee2014-05-16 16:27:35 -070036import android.media.session.MediaSession;
Hyundo Moon8cd0ae92018-12-28 15:48:23 +090037import android.media.session.MediaSession.QueueItem;
Gabriel Pealf0593bc2014-07-22 09:39:06 -070038import android.media.session.PlaybackState;
P.Y. Laligandc2045472015-03-25 14:51:50 -070039import android.net.Uri;
RoboErikf77b99f2014-06-27 11:38:59 -070040import android.os.Binder;
RoboErik01fe6612014-02-13 14:19:04 -080041import android.os.Bundle;
RoboErikd3c86422014-06-16 14:00:48 -070042import android.os.DeadObjectException;
RoboErik8ae0f342014-02-24 18:02:08 -080043import android.os.Handler;
RoboErik01fe6612014-02-13 14:19:04 -080044import android.os.IBinder;
RoboErik8ae0f342014-02-24 18:02:08 -080045import android.os.Looper;
46import android.os.Message;
Jaewan Kim77748b62018-05-03 19:43:33 +090047import android.os.Process;
Hyundo Moon24f366b2019-03-15 15:16:00 +090048import android.os.RemoteException;
RoboErik8ae0f342014-02-24 18:02:08 -080049import android.os.ResultReceiver;
RoboErikf1372422014-04-23 14:38:17 -070050import android.os.SystemClock;
RoboErik01fe6612014-02-13 14:19:04 -080051import android.util.Log;
RoboErik8ae0f342014-02-24 18:02:08 -080052import android.util.Slog;
RoboErik01fe6612014-02-13 14:19:04 -080053import android.view.KeyEvent;
54
RoboErik0dac35a2014-08-12 15:48:49 -070055import com.android.server.LocalServices;
56
RoboErika278ea72014-04-24 14:49:01 -070057import java.io.PrintWriter;
RoboErik01fe6612014-02-13 14:19:04 -080058import java.util.ArrayList;
Hyundo Moon8cd0ae92018-12-28 15:48:23 +090059import java.util.List;
RoboErik01fe6612014-02-13 14:19:04 -080060
61/**
62 * This is the system implementation of a Session. Apps will interact with the
63 * MediaSession wrapper class instead.
64 */
65public class MediaSessionRecord implements IBinder.DeathRecipient {
RoboErik07c70772014-03-20 13:33:52 -070066 private static final String TAG = "MediaSessionRecord";
Insun Kang30be970a2015-11-26 15:35:44 +090067 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
RoboErik01fe6612014-02-13 14:19:04 -080068
RoboErika8f95142014-05-05 14:23:49 -070069 /**
RoboErik19c95182014-06-23 15:38:48 -070070 * The amount of time we'll send an assumed volume after the last volume
71 * command before reverting to the last reported volume.
72 */
73 private static final int OPTIMISTIC_VOLUME_TIMEOUT = 1000;
74
RoboErik8ae0f342014-02-24 18:02:08 -080075 private final MessageHandler mHandler;
76
RoboErika5b02322014-05-07 17:05:49 -070077 private final int mOwnerPid;
78 private final int mOwnerUid;
79 private final int mUserId;
RoboErikaa4e23b2014-07-24 18:35:11 -070080 private final String mPackageName;
RoboErik01fe6612014-02-13 14:19:04 -080081 private final String mTag;
Hyundo Moon5fc8db02019-02-20 15:51:56 +090082 private final Bundle mSessionInfo;
Hyundo Moon8b1f9752019-03-14 17:44:29 +090083 private final ControllerStub mController;
Sungsoo Limaf7d46c2019-01-20 10:45:54 +090084 private final MediaSession.Token mSessionToken;
Hyundo Moon24f366b2019-03-15 15:16:00 +090085 private final SessionStub mSession;
RoboErik01fe6612014-02-13 14:19:04 -080086 private final SessionCb mSessionCb;
Hyundo Moon9b62f452019-05-08 21:45:26 +090087 private final MediaSessionService mService;
Jaewan Kim77748b62018-05-03 19:43:33 +090088 private final Context mContext;
RoboErik01fe6612014-02-13 14:19:04 -080089
RoboErik07c70772014-03-20 13:33:52 -070090 private final Object mLock = new Object();
Hyundo Moon4e4459b2019-03-26 19:18:45 +090091 private final ArrayList<ISessionControllerCallbackHolder> mControllerCallbackHolders =
Jaewan Kim742e3792017-03-22 18:22:40 +090092 new ArrayList<>();
RoboErik01fe6612014-02-13 14:19:04 -080093
RoboErike7880d82014-04-30 12:48:25 -070094 private long mFlags;
RoboErikb214efb2014-07-24 13:20:30 -070095 private PendingIntent mMediaButtonReceiver;
RoboErike34c09d2014-07-24 10:20:41 -070096 private PendingIntent mLaunchIntent;
RoboErik8ae0f342014-02-24 18:02:08 -080097
98 // TransportPerformer fields
Gabriel Pealf0593bc2014-07-22 09:39:06 -070099 private Bundle mExtras;
Jin Seok Parka1385732018-12-07 14:36:14 +0900100 // Note: Avoid unparceling the bundle inside MediaMetadata since unparceling in system process
101 // may result in throwing an exception.
RoboErik8ae0f342014-02-24 18:02:08 -0800102 private MediaMetadata mMetadata;
103 private PlaybackState mPlaybackState;
Hyundo Moon8cd0ae92018-12-28 15:48:23 +0900104 private List<QueueItem> mQueue;
Gabriel Pealf0593bc2014-07-22 09:39:06 -0700105 private CharSequence mQueueTitle;
RoboErik8ae0f342014-02-24 18:02:08 -0800106 private int mRatingType;
107 // End TransportPerformer fields
108
RoboErikb69ffd42014-05-30 14:57:59 -0700109 // Volume handling fields
RoboErik9db9bf72014-07-21 12:44:53 -0700110 private AudioAttributes mAudioAttrs;
RoboErikef3c9e92014-06-19 16:07:28 -0700111 private AudioManager mAudioManager;
RoboErik0dac35a2014-08-12 15:48:49 -0700112 private AudioManagerInternal mAudioManagerInternal;
RoboErikd2b8c942014-08-19 11:23:40 -0700113 private int mVolumeType = PlaybackInfo.PLAYBACK_TYPE_LOCAL;
RoboErikef3c9e92014-06-19 16:07:28 -0700114 private int mVolumeControlType = VolumeProvider.VOLUME_CONTROL_ABSOLUTE;
RoboErikb69ffd42014-05-30 14:57:59 -0700115 private int mMaxVolume = 0;
116 private int mCurrentVolume = 0;
RoboErik19c95182014-06-23 15:38:48 -0700117 private int mOptimisticVolume = -1;
RoboErikb69ffd42014-05-30 14:57:59 -0700118 // End volume handling fields
119
RoboErika8f95142014-05-05 14:23:49 -0700120 private boolean mIsActive = false;
RoboErik4646d282014-05-13 10:13:04 -0700121 private boolean mDestroyed = false;
RoboErik01fe6612014-02-13 14:19:04 -0800122
Hyundo Moon0c0e1bd2019-01-10 16:58:52 +0900123 private long mDuration = -1;
Jin Seok Parka1385732018-12-07 14:36:14 +0900124 private String mMetadataDescription;
125
RoboErika5b02322014-05-07 17:05:49 -0700126 public MediaSessionRecord(int ownerPid, int ownerUid, int userId, String ownerPackageName,
Hyundo Moon7969f772019-03-21 17:16:16 +0900127 ISessionCallback cb, String tag, Bundle sessionInfo,
Hyundo Moon9b62f452019-05-08 21:45:26 +0900128 MediaSessionService service, Looper handlerLooper) {
RoboErika5b02322014-05-07 17:05:49 -0700129 mOwnerPid = ownerPid;
130 mOwnerUid = ownerUid;
131 mUserId = userId;
RoboErikaa4e23b2014-07-24 18:35:11 -0700132 mPackageName = ownerPackageName;
RoboErik01fe6612014-02-13 14:19:04 -0800133 mTag = tag;
Hyundo Moon5fc8db02019-02-20 15:51:56 +0900134 mSessionInfo = sessionInfo;
Hyundo Moon8b1f9752019-03-14 17:44:29 +0900135 mController = new ControllerStub();
Sungsoo Limaf7d46c2019-01-20 10:45:54 +0900136 mSessionToken = new MediaSession.Token(mController);
Hyundo Moon24f366b2019-03-15 15:16:00 +0900137 mSession = new SessionStub();
RoboErik01fe6612014-02-13 14:19:04 -0800138 mSessionCb = new SessionCb(cb);
139 mService = service;
Jaewan Kim77748b62018-05-03 19:43:33 +0900140 mContext = mService.getContext();
Jaewan Kim92dea332017-02-02 11:52:08 +0900141 mHandler = new MessageHandler(handlerLooper);
Jaewan Kim77748b62018-05-03 19:43:33 +0900142 mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
RoboErik0dac35a2014-08-12 15:48:49 -0700143 mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
RoboErik9db9bf72014-07-21 12:44:53 -0700144 mAudioAttrs = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
RoboErik01fe6612014-02-13 14:19:04 -0800145 }
146
RoboErik07c70772014-03-20 13:33:52 -0700147 /**
Hyundo Moon24f366b2019-03-15 15:16:00 +0900148 * Get the session binder for the {@link MediaSession}.
RoboErik07c70772014-03-20 13:33:52 -0700149 *
Hyundo Moon24f366b2019-03-15 15:16:00 +0900150 * @return The session binder apps talk to.
RoboErik07c70772014-03-20 13:33:52 -0700151 */
Hyundo Moon24f366b2019-03-15 15:16:00 +0900152 public ISession getSessionBinder() {
RoboErik01fe6612014-02-13 14:19:04 -0800153 return mSession;
154 }
155
RoboErik07c70772014-03-20 13:33:52 -0700156 /**
Hyundo Moon8b1f9752019-03-14 17:44:29 +0900157 * Get the controller binder for the {@link MediaController}.
RoboErik07c70772014-03-20 13:33:52 -0700158 *
Hyundo Moon8b1f9752019-03-14 17:44:29 +0900159 * @return The controller binder apps talk to.
RoboErik07c70772014-03-20 13:33:52 -0700160 */
Hyundo Moon8b1f9752019-03-14 17:44:29 +0900161 public ISessionController getControllerBinder() {
RoboErik01fe6612014-02-13 14:19:04 -0800162 return mController;
163 }
164
RoboErik07c70772014-03-20 13:33:52 -0700165 /**
Sungsoo Limaf7d46c2019-01-20 10:45:54 +0900166 * Get the session token for creating {@link MediaController}.
167 *
168 * @return The session token.
169 */
170 public MediaSession.Token getSessionToken() {
171 return mSessionToken;
172 }
173
174 /**
RoboErik07c70772014-03-20 13:33:52 -0700175 * Get the info for this session.
176 *
177 * @return Info that identifies this session.
178 */
RoboErikaa4e23b2014-07-24 18:35:11 -0700179 public String getPackageName() {
180 return mPackageName;
181 }
182
183 /**
184 * Get the tag for the session.
185 *
186 * @return The session's tag.
187 */
188 public String getTag() {
189 return mTag;
RoboErik07c70772014-03-20 13:33:52 -0700190 }
191
RoboErikb214efb2014-07-24 13:20:30 -0700192 /**
193 * Get the intent the app set for their media button receiver.
194 *
195 * @return The pending intent set by the app or null.
196 */
197 public PendingIntent getMediaButtonReceiver() {
RoboErik6f0e4dd2014-06-17 16:56:27 -0700198 return mMediaButtonReceiver;
199 }
200
RoboErik07c70772014-03-20 13:33:52 -0700201 /**
RoboErike7880d82014-04-30 12:48:25 -0700202 * Get this session's flags.
203 *
204 * @return The flags for this session.
205 */
206 public long getFlags() {
207 return mFlags;
208 }
209
210 /**
RoboErika8f95142014-05-05 14:23:49 -0700211 * Check if this session has the specified flag.
212 *
213 * @param flag The flag to check.
214 * @return True if this session has that flag set, false otherwise.
215 */
216 public boolean hasFlag(int flag) {
217 return (mFlags & flag) != 0;
218 }
219
220 /**
Jaewan Kim92dea332017-02-02 11:52:08 +0900221 * Get the UID this session was created for.
222 *
223 * @return The UID for this session.
224 */
225 public int getUid() {
226 return mOwnerUid;
227 }
228
229 /**
RoboErika5b02322014-05-07 17:05:49 -0700230 * Get the user id this session was created for.
231 *
232 * @return The user id for this session.
233 */
234 public int getUserId() {
235 return mUserId;
236 }
237
238 /**
RoboErike7880d82014-04-30 12:48:25 -0700239 * Check if this session has system priorty and should receive media buttons
240 * before any other sessions.
241 *
242 * @return True if this is a system priority session, false otherwise
243 */
244 public boolean isSystemPriority() {
RoboErik42ea7ee2014-05-16 16:27:35 -0700245 return (mFlags & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0;
RoboErike7880d82014-04-30 12:48:25 -0700246 }
247
248 /**
RoboErik1ff5b162014-07-15 17:23:18 -0700249 * Send a volume adjustment to the session owner. Direction must be one of
250 * {@link AudioManager#ADJUST_LOWER}, {@link AudioManager#ADJUST_RAISE},
251 * {@link AudioManager#ADJUST_SAME}.
RoboErikb69ffd42014-05-30 14:57:59 -0700252 *
Hyundo Moonb1e344e2018-03-22 17:22:14 +0900253 * @param packageName The package that made the original volume request.
Jaewan Kimffdb53d2018-11-28 17:45:38 +0900254 * @param opPackageName The op package that made the original volume request.
Hyundo Moonb1e344e2018-03-22 17:22:14 +0900255 * @param pid The pid that made the original volume request.
256 * @param uid The uid that made the original volume request.
Jaewan Kim21c23e32018-05-17 16:47:31 +0900257 * @param caller caller binder. can be {@code null} if it's from the volume key.
Jaewan Kim77748b62018-05-03 19:43:33 +0900258 * @param asSystemService {@code true} if the event sent to the session as if it was come from
259 * the system service instead of the app process. This helps sessions to distinguish
260 * between the key injection by the app and key events from the hardware devices.
261 * Should be used only when the volume key events aren't handled by foreground
262 * activity. {@code false} otherwise to tell session about the real caller.
RoboErik1ff5b162014-07-15 17:23:18 -0700263 * @param direction The direction to adjust volume in.
RoboErik272e1612014-09-05 11:39:29 -0700264 * @param flags Any of the flags from {@link AudioManager}.
RoboErik272e1612014-09-05 11:39:29 -0700265 * @param useSuggested True to use adjustSuggestedStreamVolume instead of
RoboErikb69ffd42014-05-30 14:57:59 -0700266 */
Jaewan Kimffdb53d2018-11-28 17:45:38 +0900267 public void adjustVolume(String packageName, String opPackageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900268 ISessionControllerCallback caller, boolean asSystemService, int direction, int flags,
Jaewan Kim21c23e32018-05-17 16:47:31 +0900269 boolean useSuggested) {
RoboErik165809b2014-09-29 14:16:45 -0700270 int previousFlagPlaySound = flags & AudioManager.FLAG_PLAY_SOUND;
Jaewan Kim92dea332017-02-02 11:52:08 +0900271 if (isPlaybackActive() || hasFlag(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)) {
RoboErike9466802014-06-26 10:26:43 -0700272 flags &= ~AudioManager.FLAG_PLAY_SOUND;
273 }
RoboErikd2b8c942014-08-19 11:23:40 -0700274 if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
Dongwon Kanga38e1f42015-06-16 15:28:17 -0700275 // Adjust the volume with a handler not to be blocked by other system service.
Dongwon Kang500747b2015-07-20 15:59:53 -0700276 int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
Jaewan Kimffdb53d2018-11-28 17:45:38 +0900277 postAdjustLocalVolume(stream, direction, flags, opPackageName, pid, uid,
278 asSystemService, useSuggested, previousFlagPlaySound);
RoboErikef3c9e92014-06-19 16:07:28 -0700279 } else {
280 if (mVolumeControlType == VolumeProvider.VOLUME_CONTROL_FIXED) {
281 // Nothing to do, the volume cannot be changed
282 return;
283 }
RoboErik4197cb62015-01-21 15:45:32 -0800284 if (direction == AudioManager.ADJUST_TOGGLE_MUTE
285 || direction == AudioManager.ADJUST_MUTE
286 || direction == AudioManager.ADJUST_UNMUTE) {
RoboErik7c82ced2014-12-04 17:39:08 -0800287 Log.w(TAG, "Muting remote playback is not supported");
288 return;
289 }
Jaewan Kim8be71c02019-01-29 01:22:13 +0900290 if (DEBUG) {
291 Log.w(TAG, "adjusting volume, pkg=" + packageName + ", asSystemService="
292 + asSystemService + ", dir=" + direction);
293 }
Jaewan Kim21c23e32018-05-17 16:47:31 +0900294 mSessionCb.adjustVolume(packageName, pid, uid, caller, asSystemService, direction);
RoboErik19c95182014-06-23 15:38:48 -0700295
296 int volumeBefore = (mOptimisticVolume < 0 ? mCurrentVolume : mOptimisticVolume);
RoboErik1ff5b162014-07-15 17:23:18 -0700297 mOptimisticVolume = volumeBefore + direction;
RoboErik19c95182014-06-23 15:38:48 -0700298 mOptimisticVolume = Math.max(0, Math.min(mOptimisticVolume, mMaxVolume));
299 mHandler.removeCallbacks(mClearOptimisticVolumeRunnable);
300 mHandler.postDelayed(mClearOptimisticVolumeRunnable, OPTIMISTIC_VOLUME_TIMEOUT);
301 if (volumeBefore != mOptimisticVolume) {
302 pushVolumeUpdate();
303 }
RoboErik9c5b7cb2015-01-15 15:09:09 -0800304 mService.notifyRemoteVolumeChanged(flags, this);
RoboErik19c95182014-06-23 15:38:48 -0700305
306 if (DEBUG) {
307 Log.d(TAG, "Adjusted optimistic volume to " + mOptimisticVolume + " max is "
308 + mMaxVolume);
309 }
RoboErikb69ffd42014-05-30 14:57:59 -0700310 }
RoboErikb69ffd42014-05-30 14:57:59 -0700311 }
312
Jaewan Kimffdb53d2018-11-28 17:45:38 +0900313 private void setVolumeTo(String packageName, String opPackageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900314 ISessionControllerCallback caller, int value, int flags) {
RoboErikd2b8c942014-08-19 11:23:40 -0700315 if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
RoboErik9db9bf72014-07-21 12:44:53 -0700316 int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
Jaewan Kimffdb53d2018-11-28 17:45:38 +0900317 final int volumeValue = value;
318 mHandler.post(new Runnable() {
319 @Override
320 public void run() {
321 try {
322 mAudioManagerInternal.setStreamVolumeForUid(stream, volumeValue, flags,
323 opPackageName, uid);
324 } catch (IllegalArgumentException | SecurityException e) {
325 Log.e(TAG, "Cannot set volume: stream=" + stream + ", value=" + volumeValue
326 + ", flags=" + flags, e);
327 }
328 }
329 });
RoboErikef3c9e92014-06-19 16:07:28 -0700330 } else {
331 if (mVolumeControlType != VolumeProvider.VOLUME_CONTROL_ABSOLUTE) {
332 // Nothing to do. The volume can't be set directly.
333 return;
334 }
RoboErik19c95182014-06-23 15:38:48 -0700335 value = Math.max(0, Math.min(value, mMaxVolume));
Jaewan Kim21c23e32018-05-17 16:47:31 +0900336 mSessionCb.setVolumeTo(packageName, pid, uid, caller, value);
RoboErik19c95182014-06-23 15:38:48 -0700337
338 int volumeBefore = (mOptimisticVolume < 0 ? mCurrentVolume : mOptimisticVolume);
339 mOptimisticVolume = Math.max(0, Math.min(value, mMaxVolume));
340 mHandler.removeCallbacks(mClearOptimisticVolumeRunnable);
341 mHandler.postDelayed(mClearOptimisticVolumeRunnable, OPTIMISTIC_VOLUME_TIMEOUT);
342 if (volumeBefore != mOptimisticVolume) {
343 pushVolumeUpdate();
344 }
RoboErik9c5b7cb2015-01-15 15:09:09 -0800345 mService.notifyRemoteVolumeChanged(flags, this);
RoboErik19c95182014-06-23 15:38:48 -0700346
347 if (DEBUG) {
348 Log.d(TAG, "Set optimistic volume to " + mOptimisticVolume + " max is "
349 + mMaxVolume);
350 }
RoboErikb69ffd42014-05-30 14:57:59 -0700351 }
RoboErikb69ffd42014-05-30 14:57:59 -0700352 }
353
354 /**
RoboErika8f95142014-05-05 14:23:49 -0700355 * Check if this session has been set to active by the app.
RoboErik07c70772014-03-20 13:33:52 -0700356 *
RoboErika8f95142014-05-05 14:23:49 -0700357 * @return True if the session is active, false otherwise.
RoboErik07c70772014-03-20 13:33:52 -0700358 */
RoboErika8f95142014-05-05 14:23:49 -0700359 public boolean isActive() {
RoboErik4646d282014-05-13 10:13:04 -0700360 return mIsActive && !mDestroyed;
RoboErika8f95142014-05-05 14:23:49 -0700361 }
362
363 /**
Sungsoo39f479f2017-06-09 12:59:47 +0900364 * Get the playback state.
365 *
366 * @return The current playback state.
367 */
368 public PlaybackState getPlaybackState() {
369 return mPlaybackState;
370 }
371
372 /**
Jaewan Kim92dea332017-02-02 11:52:08 +0900373 * Check if the session is currently performing playback.
RoboErika8f95142014-05-05 14:23:49 -0700374 *
375 * @return True if the session is performing playback, false otherwise.
376 */
Jaewan Kim92dea332017-02-02 11:52:08 +0900377 public boolean isPlaybackActive() {
378 int state = mPlaybackState == null ? PlaybackState.STATE_NONE : mPlaybackState.getState();
379 return MediaSession.isActiveState(state);
RoboErika8f95142014-05-05 14:23:49 -0700380 }
381
RoboErik4646d282014-05-13 10:13:04 -0700382 /**
RoboErikb69ffd42014-05-30 14:57:59 -0700383 * Get the type of playback, either local or remote.
384 *
385 * @return The current type of playback.
386 */
387 public int getPlaybackType() {
RoboErikef3c9e92014-06-19 16:07:28 -0700388 return mVolumeType;
RoboErikb69ffd42014-05-30 14:57:59 -0700389 }
390
391 /**
392 * Get the local audio stream being used. Only valid if playback type is
393 * local.
394 *
395 * @return The audio stream the session is using.
396 */
RoboErik9db9bf72014-07-21 12:44:53 -0700397 public AudioAttributes getAudioAttributes() {
398 return mAudioAttrs;
RoboErikb69ffd42014-05-30 14:57:59 -0700399 }
400
401 /**
402 * Get the type of volume control. Only valid if playback type is remote.
403 *
404 * @return The volume control type being used.
405 */
406 public int getVolumeControl() {
407 return mVolumeControlType;
408 }
409
410 /**
411 * Get the max volume that can be set. Only valid if playback type is
412 * remote.
413 *
414 * @return The max volume that can be set.
415 */
416 public int getMaxVolume() {
417 return mMaxVolume;
418 }
419
420 /**
421 * Get the current volume for this session. Only valid if playback type is
422 * remote.
423 *
424 * @return The current volume of the remote playback.
425 */
426 public int getCurrentVolume() {
427 return mCurrentVolume;
428 }
429
430 /**
RoboErik19c95182014-06-23 15:38:48 -0700431 * Get the volume we'd like it to be set to. This is only valid for a short
432 * while after a call to adjust or set volume.
433 *
434 * @return The current optimistic volume or -1.
435 */
436 public int getOptimisticVolume() {
437 return mOptimisticVolume;
438 }
439
RoboErika8f95142014-05-05 14:23:49 -0700440 public boolean isTransportControlEnabled() {
RoboErik42ea7ee2014-05-16 16:27:35 -0700441 return hasFlag(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
RoboErik07c70772014-03-20 13:33:52 -0700442 }
443
RoboErik01fe6612014-02-13 14:19:04 -0800444 @Override
445 public void binderDied() {
446 mService.sessionDied(this);
447 }
448
RoboErik4646d282014-05-13 10:13:04 -0700449 /**
450 * Finish cleaning up this session, including disconnecting if connected and
451 * removing the death observer from the callback binder.
452 */
453 public void onDestroy() {
454 synchronized (mLock) {
455 if (mDestroyed) {
456 return;
457 }
RoboErik4646d282014-05-13 10:13:04 -0700458 mDestroyed = true;
RoboErik24762bf2014-08-13 15:00:21 -0700459 mHandler.post(MessageHandler.MSG_DESTROYED);
RoboErik4646d282014-05-13 10:13:04 -0700460 }
461 }
462
Hyundo Moon7969f772019-03-21 17:16:16 +0900463 public ISessionCallback getCallback() {
RoboErik4646d282014-05-13 10:13:04 -0700464 return mSessionCb.mCb;
465 }
466
Jaewan Kim8be71c02019-01-29 01:22:13 +0900467 /**
468 * Sends media button.
469 *
470 * @param packageName caller package name
471 * @param pid caller pid
472 * @param uid caller uid
473 * @param asSystemService {@code true} if the event sent to the session as if it was come from
474 * the system service instead of the app process.
475 * @param ke key events
476 * @param sequenceId (optional) sequence id. Use this only when a wake lock is needed.
477 * @param cb (optional) result receiver to receive callback. Use this only when a wake lock is
478 * needed.
479 * @return {@code true} if the attempt to send media button was successfuly.
480 * {@code false} otherwise.
481 */
482 public boolean sendMediaButton(String packageName, int pid, int uid, boolean asSystemService,
Jaewan Kim77748b62018-05-03 19:43:33 +0900483 KeyEvent ke, int sequenceId, ResultReceiver cb) {
Jaewan Kim8be71c02019-01-29 01:22:13 +0900484 return mSessionCb.sendMediaButton(packageName, pid, uid, asSystemService, ke, sequenceId,
485 cb);
RoboErik8a2cfc32014-05-16 11:19:38 -0700486 }
487
RoboErika278ea72014-04-24 14:49:01 -0700488 public void dump(PrintWriter pw, String prefix) {
489 pw.println(prefix + mTag + " " + this);
490
491 final String indent = prefix + " ";
RoboErika5b02322014-05-07 17:05:49 -0700492 pw.println(indent + "ownerPid=" + mOwnerPid + ", ownerUid=" + mOwnerUid
493 + ", userId=" + mUserId);
RoboErikaa4e23b2014-07-24 18:35:11 -0700494 pw.println(indent + "package=" + mPackageName);
RoboErik7aef77b2014-08-08 15:56:54 -0700495 pw.println(indent + "launchIntent=" + mLaunchIntent);
496 pw.println(indent + "mediaButtonReceiver=" + mMediaButtonReceiver);
RoboErik4646d282014-05-13 10:13:04 -0700497 pw.println(indent + "active=" + mIsActive);
RoboErika8f95142014-05-05 14:23:49 -0700498 pw.println(indent + "flags=" + mFlags);
RoboErika278ea72014-04-24 14:49:01 -0700499 pw.println(indent + "rating type=" + mRatingType);
Jaewan Kim742e3792017-03-22 18:22:40 +0900500 pw.println(indent + "controllers: " + mControllerCallbackHolders.size());
RoboErika8f95142014-05-05 14:23:49 -0700501 pw.println(indent + "state=" + (mPlaybackState == null ? null : mPlaybackState.toString()));
RoboErik7aef77b2014-08-08 15:56:54 -0700502 pw.println(indent + "audioAttrs=" + mAudioAttrs);
503 pw.println(indent + "volumeType=" + mVolumeType + ", controlType=" + mVolumeControlType
504 + ", max=" + mMaxVolume + ", current=" + mCurrentVolume);
Jin Seok Parka1385732018-12-07 14:36:14 +0900505 pw.println(indent + "metadata: " + mMetadataDescription);
RoboErik7aef77b2014-08-08 15:56:54 -0700506 pw.println(indent + "queueTitle=" + mQueueTitle + ", size="
Hyundo Moon8cd0ae92018-12-28 15:48:23 +0900507 + (mQueue == null ? 0 : mQueue.size()));
RoboErika278ea72014-04-24 14:49:01 -0700508 }
509
RoboErikaa4e23b2014-07-24 18:35:11 -0700510 @Override
511 public String toString() {
Jaewan Kim92dea332017-02-02 11:52:08 +0900512 return mPackageName + "/" + mTag + " (userId=" + mUserId + ")";
RoboErikaa4e23b2014-07-24 18:35:11 -0700513 }
514
Dongwon Kang500747b2015-07-20 15:59:53 -0700515 private void postAdjustLocalVolume(final int stream, final int direction, final int flags,
Jaewan Kimffdb53d2018-11-28 17:45:38 +0900516 final String callingOpPackageName, final int callingPid, final int callingUid,
517 final boolean asSystemService, final boolean useSuggested,
518 final int previousFlagPlaySound) {
Jaewan Kim8be71c02019-01-29 01:22:13 +0900519 if (DEBUG) {
520 Log.w(TAG, "adjusting local volume, stream=" + stream + ", dir=" + direction
521 + ", asSystemService=" + asSystemService + ", useSuggested=" + useSuggested);
522 }
Jaewan Kimffdb53d2018-11-28 17:45:38 +0900523 // Must use opPackageName for adjusting volumes with UID.
524 final String opPackageName;
525 final int uid;
526 if (asSystemService) {
527 opPackageName = mContext.getOpPackageName();
528 uid = Process.SYSTEM_UID;
529 } else {
530 opPackageName = callingOpPackageName;
531 uid = callingUid;
532 }
Dongwon Kanga38e1f42015-06-16 15:28:17 -0700533 mHandler.post(new Runnable() {
534 @Override
535 public void run() {
Hyundo Moon739d6c22017-09-18 17:01:48 +0900536 try {
537 if (useSuggested) {
538 if (AudioSystem.isStreamActive(stream, 0)) {
539 mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(stream,
Jaewan Kimffdb53d2018-11-28 17:45:38 +0900540 direction, flags, opPackageName, uid);
Hyundo Moon739d6c22017-09-18 17:01:48 +0900541 } else {
542 mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(
543 AudioManager.USE_DEFAULT_STREAM_TYPE, direction,
Jaewan Kimffdb53d2018-11-28 17:45:38 +0900544 flags | previousFlagPlaySound, opPackageName, uid);
Hyundo Moon739d6c22017-09-18 17:01:48 +0900545 }
Dongwon Kang500747b2015-07-20 15:59:53 -0700546 } else {
Hyundo Moon739d6c22017-09-18 17:01:48 +0900547 mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags,
Jaewan Kimffdb53d2018-11-28 17:45:38 +0900548 opPackageName, uid);
Dongwon Kang500747b2015-07-20 15:59:53 -0700549 }
Jean-Michel Trivi6565c0d2018-07-09 15:51:16 -0700550 } catch (IllegalArgumentException | SecurityException e) {
Hyundo Moon739d6c22017-09-18 17:01:48 +0900551 Log.e(TAG, "Cannot adjust volume: direction=" + direction + ", stream="
Jaewan Kimffdb53d2018-11-28 17:45:38 +0900552 + stream + ", flags=" + flags + ", opPackageName=" + opPackageName
Hyundo Moon739d6c22017-09-18 17:01:48 +0900553 + ", uid=" + uid + ", useSuggested=" + useSuggested
554 + ", previousFlagPlaySound=" + previousFlagPlaySound, e);
Dongwon Kang500747b2015-07-20 15:59:53 -0700555 }
Dongwon Kanga38e1f42015-06-16 15:28:17 -0700556 }
557 });
558 }
559
Jaewan Kim742e3792017-03-22 18:22:40 +0900560 private void logCallbackException(
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900561 String msg, ISessionControllerCallbackHolder holder, Exception e) {
Jaewan Kim742e3792017-03-22 18:22:40 +0900562 Log.v(TAG, msg + ", this=" + this + ", callback package=" + holder.mPackageName
563 + ", exception=" + e);
564 }
565
RoboErik8ae0f342014-02-24 18:02:08 -0800566 private void pushPlaybackStateUpdate() {
RoboErik07c70772014-03-20 13:33:52 -0700567 synchronized (mLock) {
RoboErik4646d282014-05-13 10:13:04 -0700568 if (mDestroyed) {
569 return;
570 }
Jaewan Kim742e3792017-03-22 18:22:40 +0900571 for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900572 ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
RoboErik8ae0f342014-02-24 18:02:08 -0800573 try {
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900574 holder.mCallback.onPlaybackStateChanged(mPlaybackState);
575 } catch (DeadObjectException e) {
576 mControllerCallbackHolders.remove(i);
577 logCallbackException("Removing dead callback in pushPlaybackStateUpdate",
578 holder, e);
579 } catch (RemoteException e) {
580 logCallbackException("unexpected exception in pushPlaybackStateUpdate",
581 holder, e);
RoboErik8ae0f342014-02-24 18:02:08 -0800582 }
583 }
584 }
585 }
586
587 private void pushMetadataUpdate() {
RoboErik07c70772014-03-20 13:33:52 -0700588 synchronized (mLock) {
RoboErik4646d282014-05-13 10:13:04 -0700589 if (mDestroyed) {
590 return;
591 }
Jaewan Kim742e3792017-03-22 18:22:40 +0900592 for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900593 ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
RoboErik8ae0f342014-02-24 18:02:08 -0800594 try {
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900595 holder.mCallback.onMetadataChanged(mMetadata);
596 } catch (DeadObjectException e) {
597 mControllerCallbackHolders.remove(i);
598 logCallbackException("Removing dead callback in pushMetadataUpdate", holder, e);
599 } catch (RemoteException e) {
600 logCallbackException("unexpected exception in pushMetadataUpdate", holder, e);
RoboErik19c95182014-06-23 15:38:48 -0700601 }
602 }
603 }
604 }
605
Gabriel Pealf0593bc2014-07-22 09:39:06 -0700606 private void pushQueueUpdate() {
607 synchronized (mLock) {
608 if (mDestroyed) {
609 return;
610 }
Jaewan Kim742e3792017-03-22 18:22:40 +0900611 for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900612 ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
Gabriel Pealf0593bc2014-07-22 09:39:06 -0700613 try {
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900614 holder.mCallback.onQueueChanged(mQueue == null ? null :
Hyundo Moonbb07e9b2019-05-09 16:03:51 +0900615 new ParceledListSlice<>(mQueue));
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900616 } catch (DeadObjectException e) {
617 mControllerCallbackHolders.remove(i);
618 logCallbackException("Removing dead callback in pushQueueUpdate", holder, e);
619 } catch (RemoteException e) {
620 logCallbackException("unexpected exception in pushQueueUpdate", holder, e);
Gabriel Pealf0593bc2014-07-22 09:39:06 -0700621 }
622 }
623 }
624 }
625
626 private void pushQueueTitleUpdate() {
627 synchronized (mLock) {
628 if (mDestroyed) {
629 return;
630 }
Jaewan Kim742e3792017-03-22 18:22:40 +0900631 for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900632 ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
Gabriel Pealf0593bc2014-07-22 09:39:06 -0700633 try {
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900634 holder.mCallback.onQueueTitleChanged(mQueueTitle);
635 } catch (DeadObjectException e) {
636 mControllerCallbackHolders.remove(i);
637 logCallbackException("Removing dead callback in pushQueueTitleUpdate",
638 holder, e);
639 } catch (RemoteException e) {
640 logCallbackException("unexpected exception in pushQueueTitleUpdate", holder, e);
Gabriel Pealf0593bc2014-07-22 09:39:06 -0700641 }
642 }
643 }
644 }
645
646 private void pushExtrasUpdate() {
647 synchronized (mLock) {
648 if (mDestroyed) {
649 return;
650 }
Jaewan Kim742e3792017-03-22 18:22:40 +0900651 for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900652 ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
Gabriel Pealf0593bc2014-07-22 09:39:06 -0700653 try {
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900654 holder.mCallback.onExtrasChanged(mExtras);
655 } catch (DeadObjectException e) {
656 mControllerCallbackHolders.remove(i);
657 logCallbackException("Removing dead callback in pushExtrasUpdate", holder, e);
658 } catch (RemoteException e) {
659 logCallbackException("unexpected exception in pushExtrasUpdate", holder, e);
Gabriel Pealf0593bc2014-07-22 09:39:06 -0700660 }
661 }
662 }
663 }
664
RoboErik19c95182014-06-23 15:38:48 -0700665 private void pushVolumeUpdate() {
666 synchronized (mLock) {
667 if (mDestroyed) {
668 return;
669 }
Sungsoo Lim39d07a32019-01-20 13:02:01 +0900670 PlaybackInfo info = getVolumeAttributes();
Jaewan Kim742e3792017-03-22 18:22:40 +0900671 for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900672 ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
RoboErik19c95182014-06-23 15:38:48 -0700673 try {
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900674 holder.mCallback.onVolumeInfoChanged(info);
675 } catch (DeadObjectException e) {
676 mControllerCallbackHolders.remove(i);
677 logCallbackException("Removing dead callback in pushVolumeUpdate", holder, e);
678 } catch (RemoteException e) {
679 logCallbackException("unexpected exception in pushVolumeUpdate", holder, e);
RoboErik8ae0f342014-02-24 18:02:08 -0800680 }
681 }
682 }
683 }
684
RoboErik8ae0f342014-02-24 18:02:08 -0800685 private void pushEvent(String event, Bundle data) {
RoboErik07c70772014-03-20 13:33:52 -0700686 synchronized (mLock) {
RoboErik4646d282014-05-13 10:13:04 -0700687 if (mDestroyed) {
688 return;
689 }
Jaewan Kim742e3792017-03-22 18:22:40 +0900690 for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900691 ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
RoboErik8ae0f342014-02-24 18:02:08 -0800692 try {
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900693 holder.mCallback.onEvent(event, data);
694 } catch (DeadObjectException e) {
695 mControllerCallbackHolders.remove(i);
696 logCallbackException("Removing dead callback in pushEvent", holder, e);
697 } catch (RemoteException e) {
698 logCallbackException("unexpected exception in pushEvent", holder, e);
RoboErik8ae0f342014-02-24 18:02:08 -0800699 }
700 }
701 }
702 }
703
RoboErik24762bf2014-08-13 15:00:21 -0700704 private void pushSessionDestroyed() {
705 synchronized (mLock) {
706 // This is the only method that may be (and can only be) called
707 // after the session is destroyed.
708 if (!mDestroyed) {
709 return;
710 }
Jaewan Kim742e3792017-03-22 18:22:40 +0900711 for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900712 ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
RoboErik24762bf2014-08-13 15:00:21 -0700713 try {
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900714 holder.mCallback.onSessionDestroyed();
715 } catch (DeadObjectException e) {
716 mControllerCallbackHolders.remove(i);
717 logCallbackException("Removing dead callback in pushSessionDestroyed",
718 holder, e);
719 } catch (RemoteException e) {
720 logCallbackException("unexpected exception in pushSessionDestroyed", holder, e);
RoboErik24762bf2014-08-13 15:00:21 -0700721 }
722 }
723 // After notifying clear all listeners
Jaewan Kim742e3792017-03-22 18:22:40 +0900724 mControllerCallbackHolders.clear();
RoboErik24762bf2014-08-13 15:00:21 -0700725 }
726 }
727
RoboErikf1372422014-04-23 14:38:17 -0700728 private PlaybackState getStateWithUpdatedPosition() {
RoboErikdf382ca2014-09-29 13:21:47 -0700729 PlaybackState state;
Jin Seok Parka1385732018-12-07 14:36:14 +0900730 long duration;
RoboErikdf382ca2014-09-29 13:21:47 -0700731 synchronized (mLock) {
732 state = mPlaybackState;
Jin Seok Parka1385732018-12-07 14:36:14 +0900733 duration = mDuration;
RoboErikf1372422014-04-23 14:38:17 -0700734 }
735 PlaybackState result = null;
736 if (state != null) {
RoboErik79fa4632014-05-27 16:49:09 -0700737 if (state.getState() == PlaybackState.STATE_PLAYING
738 || state.getState() == PlaybackState.STATE_FAST_FORWARDING
739 || state.getState() == PlaybackState.STATE_REWINDING) {
RoboErikf1372422014-04-23 14:38:17 -0700740 long updateTime = state.getLastPositionUpdateTime();
RoboErikc785a782014-07-14 13:40:43 -0700741 long currentTime = SystemClock.elapsedRealtime();
RoboErikf1372422014-04-23 14:38:17 -0700742 if (updateTime > 0) {
RoboErikc785a782014-07-14 13:40:43 -0700743 long position = (long) (state.getPlaybackSpeed()
744 * (currentTime - updateTime)) + state.getPosition();
RoboErikf1372422014-04-23 14:38:17 -0700745 if (duration >= 0 && position > duration) {
746 position = duration;
747 } else if (position < 0) {
748 position = 0;
749 }
RoboErikc785a782014-07-14 13:40:43 -0700750 PlaybackState.Builder builder = new PlaybackState.Builder(state);
751 builder.setState(state.getState(), position, state.getPlaybackSpeed(),
752 currentTime);
753 result = builder.build();
RoboErikf1372422014-04-23 14:38:17 -0700754 }
755 }
756 }
757 return result == null ? state : result;
758 }
759
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900760 private int getControllerHolderIndexForCb(ISessionControllerCallback cb) {
761 IBinder binder = cb.asBinder();
Jaewan Kim742e3792017-03-22 18:22:40 +0900762 for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
Hyundo Moon4e4459b2019-03-26 19:18:45 +0900763 if (binder.equals(mControllerCallbackHolders.get(i).mCallback.asBinder())) {
RoboErikd3c86422014-06-16 14:00:48 -0700764 return i;
765 }
766 }
767 return -1;
768 }
769
Sungsoo Lim39d07a32019-01-20 13:02:01 +0900770 private PlaybackInfo getVolumeAttributes() {
771 int volumeType;
772 AudioAttributes attributes;
773 synchronized (mLock) {
774 if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_REMOTE) {
775 int current = mOptimisticVolume != -1 ? mOptimisticVolume : mCurrentVolume;
776 return new PlaybackInfo(mVolumeType, mVolumeControlType, mMaxVolume, current,
777 mAudioAttrs);
778 }
779 volumeType = mVolumeType;
780 attributes = mAudioAttrs;
781 }
782 int stream = AudioAttributes.toLegacyStreamType(attributes);
783 int max = mAudioManager.getStreamMaxVolume(stream);
784 int current = mAudioManager.getStreamVolume(stream);
785 return new PlaybackInfo(volumeType, VolumeProvider.VOLUME_CONTROL_ABSOLUTE, max,
786 current, attributes);
787 }
788
RoboErik19c95182014-06-23 15:38:48 -0700789 private final Runnable mClearOptimisticVolumeRunnable = new Runnable() {
790 @Override
791 public void run() {
792 boolean needUpdate = (mOptimisticVolume != mCurrentVolume);
793 mOptimisticVolume = -1;
794 if (needUpdate) {
795 pushVolumeUpdate();
796 }
797 }
798 };
799
Hyundo Moon24f366b2019-03-15 15:16:00 +0900800 private final class SessionStub extends ISession.Stub {
RoboErik01fe6612014-02-13 14:19:04 -0800801 @Override
Hyundo Moon24f366b2019-03-15 15:16:00 +0900802 public void destroySession() throws RemoteException {
Dongwon Kang0c1d4482017-03-28 10:54:46 -0700803 final long token = Binder.clearCallingIdentity();
804 try {
805 mService.destroySession(MediaSessionRecord.this);
806 } finally {
807 Binder.restoreCallingIdentity(token);
808 }
RoboErik01fe6612014-02-13 14:19:04 -0800809 }
810
811 @Override
Hyundo Moon24f366b2019-03-15 15:16:00 +0900812 public void sendEvent(String event, Bundle data) throws RemoteException {
RoboErikdf382ca2014-09-29 13:21:47 -0700813 mHandler.post(MessageHandler.MSG_SEND_EVENT, event,
814 data == null ? null : new Bundle(data));
RoboErik01fe6612014-02-13 14:19:04 -0800815 }
816
817 @Override
Hyundo Moon24f366b2019-03-15 15:16:00 +0900818 public ISessionController getController() throws RemoteException {
RoboErik01fe6612014-02-13 14:19:04 -0800819 return mController;
820 }
821
822 @Override
Hyundo Moon24f366b2019-03-15 15:16:00 +0900823 public void setActive(boolean active) throws RemoteException {
RoboErika8f95142014-05-05 14:23:49 -0700824 mIsActive = active;
Jaewan Kim83c46352017-03-30 18:19:17 +0900825 final long token = Binder.clearCallingIdentity();
826 try {
827 mService.updateSession(MediaSessionRecord.this);
828 } finally {
829 Binder.restoreCallingIdentity(token);
830 }
RoboErika8f95142014-05-05 14:23:49 -0700831 mHandler.post(MessageHandler.MSG_UPDATE_SESSION_STATE);
RoboErik01fe6612014-02-13 14:19:04 -0800832 }
833
RoboErik8ae0f342014-02-24 18:02:08 -0800834 @Override
Hyundo Moon24f366b2019-03-15 15:16:00 +0900835 public void setFlags(int flags) throws RemoteException {
RoboErik42ea7ee2014-05-16 16:27:35 -0700836 if ((flags & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) {
Sungsoo Lim39d07a32019-01-20 13:02:01 +0900837 int pid = Binder.getCallingPid();
838 int uid = Binder.getCallingUid();
RoboErike7880d82014-04-30 12:48:25 -0700839 mService.enforcePhoneStatePermission(pid, uid);
840 }
RoboErike7880d82014-04-30 12:48:25 -0700841 mFlags = flags;
Jaewan Kimfa85b602017-10-10 16:49:58 +0900842 if ((flags & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) {
843 final long token = Binder.clearCallingIdentity();
844 try {
845 mService.setGlobalPrioritySession(MediaSessionRecord.this);
846 } finally {
847 Binder.restoreCallingIdentity(token);
848 }
849 }
RoboErika8f95142014-05-05 14:23:49 -0700850 mHandler.post(MessageHandler.MSG_UPDATE_SESSION_STATE);
RoboErike7880d82014-04-30 12:48:25 -0700851 }
852
853 @Override
Hyundo Moon24f366b2019-03-15 15:16:00 +0900854 public void setMediaButtonReceiver(PendingIntent pi) throws RemoteException {
RoboErikb214efb2014-07-24 13:20:30 -0700855 mMediaButtonReceiver = pi;
Jaewan Kim92dea332017-02-02 11:52:08 +0900856 final long token = Binder.clearCallingIdentity();
857 try {
858 mService.onMediaButtonReceiverChanged(MediaSessionRecord.this);
859 } finally {
860 Binder.restoreCallingIdentity(token);
861 }
RoboErik6f0e4dd2014-06-17 16:56:27 -0700862 }
863
864 @Override
Hyundo Moon24f366b2019-03-15 15:16:00 +0900865 public void setLaunchPendingIntent(PendingIntent pi) throws RemoteException {
RoboErike34c09d2014-07-24 10:20:41 -0700866 mLaunchIntent = pi;
867 }
868
869 @Override
Hyundo Moon24f366b2019-03-15 15:16:00 +0900870 public void setMetadata(MediaMetadata metadata, long duration, String metadataDescription)
871 throws RemoteException {
RoboErikdf382ca2014-09-29 13:21:47 -0700872 synchronized (mLock) {
RoboErik82df2c02014-10-08 10:38:42 -0700873 MediaMetadata temp = metadata == null ? null : new MediaMetadata.Builder(metadata)
874 .build();
875 // This is to guarantee that the underlying bundle is unparceled
876 // before we set it to prevent concurrent reads from throwing an
877 // exception
RoboErik421c9df2014-10-15 12:17:43 -0700878 if (temp != null) {
879 temp.size();
880 }
RoboErik82df2c02014-10-08 10:38:42 -0700881 mMetadata = temp;
Jin Seok Parka1385732018-12-07 14:36:14 +0900882 mDuration = duration;
883 mMetadataDescription = metadataDescription;
RoboErikdf382ca2014-09-29 13:21:47 -0700884 }
RoboErik8ae0f342014-02-24 18:02:08 -0800885 mHandler.post(MessageHandler.MSG_UPDATE_METADATA);
886 }
887
888 @Override
Hyundo Moon24f366b2019-03-15 15:16:00 +0900889 public void setPlaybackState(PlaybackState state) throws RemoteException {
Jaewan Kim92dea332017-02-02 11:52:08 +0900890 int oldState = mPlaybackState == null
891 ? PlaybackState.STATE_NONE : mPlaybackState.getState();
892 int newState = state == null
893 ? PlaybackState.STATE_NONE : state.getState();
RoboErikdf382ca2014-09-29 13:21:47 -0700894 synchronized (mLock) {
895 mPlaybackState = state;
896 }
Jaewan Kim92dea332017-02-02 11:52:08 +0900897 final long token = Binder.clearCallingIdentity();
898 try {
899 mService.onSessionPlaystateChanged(MediaSessionRecord.this, oldState, newState);
900 } finally {
901 Binder.restoreCallingIdentity(token);
902 }
RoboErik8ae0f342014-02-24 18:02:08 -0800903 mHandler.post(MessageHandler.MSG_UPDATE_PLAYBACK_STATE);
904 }
905
906 @Override
Hyundo Moonbb07e9b2019-05-09 16:03:51 +0900907 public void setQueue(ParceledListSlice queue) throws RemoteException {
RoboErikdf382ca2014-09-29 13:21:47 -0700908 synchronized (mLock) {
Hyundo Moon24f366b2019-03-15 15:16:00 +0900909 mQueue = queue == null ? null : (List<QueueItem>) queue.getList();
RoboErikdf382ca2014-09-29 13:21:47 -0700910 }
Gabriel Pealf0593bc2014-07-22 09:39:06 -0700911 mHandler.post(MessageHandler.MSG_UPDATE_QUEUE);
912 }
913
914 @Override
Hyundo Moon24f366b2019-03-15 15:16:00 +0900915 public void setQueueTitle(CharSequence title) throws RemoteException {
Gabriel Pealf0593bc2014-07-22 09:39:06 -0700916 mQueueTitle = title;
917 mHandler.post(MessageHandler.MSG_UPDATE_QUEUE_TITLE);
918 }
919
920 @Override
Hyundo Moon24f366b2019-03-15 15:16:00 +0900921 public void setExtras(Bundle extras) throws RemoteException {
RoboErikdf382ca2014-09-29 13:21:47 -0700922 synchronized (mLock) {
923 mExtras = extras == null ? null : new Bundle(extras);
924 }
Gabriel Pealf0593bc2014-07-22 09:39:06 -0700925 mHandler.post(MessageHandler.MSG_UPDATE_EXTRAS);
926 }
927
928 @Override
Hyundo Moon24f366b2019-03-15 15:16:00 +0900929 public void setRatingType(int type) throws RemoteException {
RoboErik8ae0f342014-02-24 18:02:08 -0800930 mRatingType = type;
931 }
RoboErik07c70772014-03-20 13:33:52 -0700932
933 @Override
Hyundo Moon24f366b2019-03-15 15:16:00 +0900934 public void setCurrentVolume(int volume) throws RemoteException {
RoboErikb69ffd42014-05-30 14:57:59 -0700935 mCurrentVolume = volume;
RoboErik19c95182014-06-23 15:38:48 -0700936 mHandler.post(MessageHandler.MSG_UPDATE_VOLUME);
RoboErikb69ffd42014-05-30 14:57:59 -0700937 }
938
939 @Override
Hyundo Moon24f366b2019-03-15 15:16:00 +0900940 public void setPlaybackToLocal(AudioAttributes attributes) throws RemoteException {
RoboErik9db9bf72014-07-21 12:44:53 -0700941 boolean typeChanged;
942 synchronized (mLock) {
RoboErikd2b8c942014-08-19 11:23:40 -0700943 typeChanged = mVolumeType == PlaybackInfo.PLAYBACK_TYPE_REMOTE;
944 mVolumeType = PlaybackInfo.PLAYBACK_TYPE_LOCAL;
RoboErik9db9bf72014-07-21 12:44:53 -0700945 if (attributes != null) {
946 mAudioAttrs = attributes;
947 } else {
948 Log.e(TAG, "Received null audio attributes, using existing attributes");
949 }
RoboErikb69ffd42014-05-30 14:57:59 -0700950 }
RoboErik19c95182014-06-23 15:38:48 -0700951 if (typeChanged) {
Jaewan Kim83c46352017-03-30 18:19:17 +0900952 final long token = Binder.clearCallingIdentity();
953 try {
954 mService.onSessionPlaybackTypeChanged(MediaSessionRecord.this);
955 } finally {
956 Binder.restoreCallingIdentity(token);
957 }
John Spurlockbfa98592015-03-09 23:13:57 -0400958 mHandler.post(MessageHandler.MSG_UPDATE_VOLUME);
RoboErik19c95182014-06-23 15:38:48 -0700959 }
RoboErikb69ffd42014-05-30 14:57:59 -0700960 }
961
RoboErik9db9bf72014-07-21 12:44:53 -0700962 @Override
Hyundo Moon24f366b2019-03-15 15:16:00 +0900963 public void setPlaybackToRemote(int control, int max) throws RemoteException {
RoboErik9db9bf72014-07-21 12:44:53 -0700964 boolean typeChanged;
965 synchronized (mLock) {
RoboErikd2b8c942014-08-19 11:23:40 -0700966 typeChanged = mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL;
967 mVolumeType = PlaybackInfo.PLAYBACK_TYPE_REMOTE;
RoboErik9db9bf72014-07-21 12:44:53 -0700968 mVolumeControlType = control;
969 mMaxVolume = max;
970 }
971 if (typeChanged) {
Jaewan Kim83c46352017-03-30 18:19:17 +0900972 final long token = Binder.clearCallingIdentity();
973 try {
974 mService.onSessionPlaybackTypeChanged(MediaSessionRecord.this);
975 } finally {
976 Binder.restoreCallingIdentity(token);
977 }
John Spurlockbfa98592015-03-09 23:13:57 -0400978 mHandler.post(MessageHandler.MSG_UPDATE_VOLUME);
RoboErik9db9bf72014-07-21 12:44:53 -0700979 }
RoboErikb69ffd42014-05-30 14:57:59 -0700980 }
RoboErik01fe6612014-02-13 14:19:04 -0800981 }
982
983 class SessionCb {
Hyundo Moon7969f772019-03-21 17:16:16 +0900984 private final ISessionCallback mCb;
RoboErik01fe6612014-02-13 14:19:04 -0800985
Hyundo Moon7969f772019-03-21 17:16:16 +0900986 SessionCb(ISessionCallback cb) {
RoboErik01fe6612014-02-13 14:19:04 -0800987 mCb = cb;
988 }
989
Jaewan Kim77748b62018-05-03 19:43:33 +0900990 public boolean sendMediaButton(String packageName, int pid, int uid,
991 boolean asSystemService, KeyEvent keyEvent, int sequenceId, ResultReceiver cb) {
RoboErik01fe6612014-02-13 14:19:04 -0800992 try {
Jaewan Kim77748b62018-05-03 19:43:33 +0900993 if (asSystemService) {
Hyundo Moon7969f772019-03-21 17:16:16 +0900994 mCb.onMediaButton(mContext.getPackageName(), Process.myPid(),
Jaewan Kim21c23e32018-05-17 16:47:31 +0900995 Process.SYSTEM_UID, createMediaButtonIntent(keyEvent), sequenceId, cb);
Jaewan Kim77748b62018-05-03 19:43:33 +0900996 } else {
Hyundo Moon7969f772019-03-21 17:16:16 +0900997 mCb.onMediaButton(packageName, pid, uid,
Jaewan Kim21c23e32018-05-17 16:47:31 +0900998 createMediaButtonIntent(keyEvent), sequenceId, cb);
Jaewan Kim77748b62018-05-03 19:43:33 +0900999 }
RoboErik79fa4632014-05-27 16:49:09 -07001000 return true;
Hyundo Moon7969f772019-03-21 17:16:16 +09001001 } catch (RemoteException e) {
RoboErik8ae0f342014-02-24 18:02:08 -08001002 Slog.e(TAG, "Remote failure in sendMediaRequest.", e);
RoboErik01fe6612014-02-13 14:19:04 -08001003 }
RoboErik79fa4632014-05-27 16:49:09 -07001004 return false;
RoboErik01fe6612014-02-13 14:19:04 -08001005 }
1006
Jaewan Kim21c23e32018-05-17 16:47:31 +09001007 public boolean sendMediaButton(String packageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001008 ISessionControllerCallback caller, boolean asSystemService,
Jaewan Kim21c23e32018-05-17 16:47:31 +09001009 KeyEvent keyEvent) {
RoboErik01fe6612014-02-13 14:19:04 -08001010 try {
Jaewan Kim21c23e32018-05-17 16:47:31 +09001011 if (asSystemService) {
Hyundo Moon7969f772019-03-21 17:16:16 +09001012 mCb.onMediaButton(mContext.getPackageName(), Process.myPid(),
Jaewan Kim21c23e32018-05-17 16:47:31 +09001013 Process.SYSTEM_UID, createMediaButtonIntent(keyEvent), 0, null);
1014 } else {
Hyundo Moon7969f772019-03-21 17:16:16 +09001015 mCb.onMediaButtonFromController(packageName, pid, uid, caller,
Jaewan Kim21c23e32018-05-17 16:47:31 +09001016 createMediaButtonIntent(keyEvent));
1017 }
1018 return true;
Hyundo Moon7969f772019-03-21 17:16:16 +09001019 } catch (RemoteException e) {
Jaewan Kim21c23e32018-05-17 16:47:31 +09001020 Slog.e(TAG, "Remote failure in sendMediaRequest.", e);
1021 }
1022 return false;
1023 }
1024
1025 public void sendCommand(String packageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001026 ISessionControllerCallback caller, String command, Bundle args, ResultReceiver cb) {
Jaewan Kim21c23e32018-05-17 16:47:31 +09001027 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001028 mCb.onCommand(packageName, pid, uid, caller, command, args, cb);
1029 } catch (RemoteException e) {
RoboErik8ae0f342014-02-24 18:02:08 -08001030 Slog.e(TAG, "Remote failure in sendCommand.", e);
RoboErik01fe6612014-02-13 14:19:04 -08001031 }
1032 }
1033
Jaewan Kim21c23e32018-05-17 16:47:31 +09001034 public void sendCustomAction(String packageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001035 ISessionControllerCallback caller, String action,
Hyundo Moonb1e344e2018-03-22 17:22:14 +09001036 Bundle args) {
Gabriel Pealf364f942014-07-22 09:39:06 -07001037 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001038 mCb.onCustomAction(packageName, pid, uid, caller, action, args);
1039 } catch (RemoteException e) {
Gabriel Pealf364f942014-07-22 09:39:06 -07001040 Slog.e(TAG, "Remote failure in sendCustomAction.", e);
1041 }
1042 }
1043
Jaewan Kim21c23e32018-05-17 16:47:31 +09001044 public void prepare(String packageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001045 ISessionControllerCallback caller) {
Donghyun Cho22188f12016-02-02 17:33:18 +09001046 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001047 mCb.onPrepare(packageName, pid, uid, caller);
1048 } catch (RemoteException e) {
Donghyun Cho22188f12016-02-02 17:33:18 +09001049 Slog.e(TAG, "Remote failure in prepare.", e);
1050 }
1051 }
1052
Jaewan Kim21c23e32018-05-17 16:47:31 +09001053 public void prepareFromMediaId(String packageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001054 ISessionControllerCallback caller, String mediaId, Bundle extras) {
Donghyun Cho22188f12016-02-02 17:33:18 +09001055 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001056 mCb.onPrepareFromMediaId(packageName, pid, uid, caller, mediaId, extras);
1057 } catch (RemoteException e) {
Donghyun Cho22188f12016-02-02 17:33:18 +09001058 Slog.e(TAG, "Remote failure in prepareFromMediaId.", e);
1059 }
1060 }
1061
Jaewan Kim21c23e32018-05-17 16:47:31 +09001062 public void prepareFromSearch(String packageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001063 ISessionControllerCallback caller, String query, Bundle extras) {
Donghyun Cho22188f12016-02-02 17:33:18 +09001064 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001065 mCb.onPrepareFromSearch(packageName, pid, uid, caller, query, extras);
1066 } catch (RemoteException e) {
Donghyun Cho22188f12016-02-02 17:33:18 +09001067 Slog.e(TAG, "Remote failure in prepareFromSearch.", e);
1068 }
1069 }
1070
Jaewan Kim21c23e32018-05-17 16:47:31 +09001071 public void prepareFromUri(String packageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001072 ISessionControllerCallback caller, Uri uri, Bundle extras) {
Donghyun Cho22188f12016-02-02 17:33:18 +09001073 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001074 mCb.onPrepareFromUri(packageName, pid, uid, caller, uri, extras);
1075 } catch (RemoteException e) {
Donghyun Cho22188f12016-02-02 17:33:18 +09001076 Slog.e(TAG, "Remote failure in prepareFromUri.", e);
1077 }
1078 }
1079
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001080 public void play(String packageName, int pid, int uid, ISessionControllerCallback caller) {
RoboErik8ae0f342014-02-24 18:02:08 -08001081 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001082 mCb.onPlay(packageName, pid, uid, caller);
1083 } catch (RemoteException e) {
RoboErik8ae0f342014-02-24 18:02:08 -08001084 Slog.e(TAG, "Remote failure in play.", e);
1085 }
RoboErik01fe6612014-02-13 14:19:04 -08001086 }
1087
Jaewan Kim21c23e32018-05-17 16:47:31 +09001088 public void playFromMediaId(String packageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001089 ISessionControllerCallback caller, String mediaId, Bundle extras) {
Gabriel Pealf0593bc2014-07-22 09:39:06 -07001090 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001091 mCb.onPlayFromMediaId(packageName, pid, uid, caller, mediaId, extras);
1092 } catch (RemoteException e) {
Donghyun Cho22188f12016-02-02 17:33:18 +09001093 Slog.e(TAG, "Remote failure in playFromMediaId.", e);
Gabriel Pealf0593bc2014-07-22 09:39:06 -07001094 }
1095 }
1096
Jaewan Kim21c23e32018-05-17 16:47:31 +09001097 public void playFromSearch(String packageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001098 ISessionControllerCallback caller, String query, Bundle extras) {
Gabriel Pealf0593bc2014-07-22 09:39:06 -07001099 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001100 mCb.onPlayFromSearch(packageName, pid, uid, caller, query, extras);
1101 } catch (RemoteException e) {
Gabriel Pealf0593bc2014-07-22 09:39:06 -07001102 Slog.e(TAG, "Remote failure in playFromSearch.", e);
1103 }
1104 }
1105
Jaewan Kim21c23e32018-05-17 16:47:31 +09001106 public void playFromUri(String packageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001107 ISessionControllerCallback caller, Uri uri, Bundle extras) {
P.Y. Laligandc2045472015-03-25 14:51:50 -07001108 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001109 mCb.onPlayFromUri(packageName, pid, uid, caller, uri, extras);
1110 } catch (RemoteException e) {
P.Y. Laligandc2045472015-03-25 14:51:50 -07001111 Slog.e(TAG, "Remote failure in playFromUri.", e);
1112 }
1113 }
1114
Jaewan Kim21c23e32018-05-17 16:47:31 +09001115 public void skipToTrack(String packageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001116 ISessionControllerCallback caller, long id) {
Gabriel Pealf0593bc2014-07-22 09:39:06 -07001117 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001118 mCb.onSkipToTrack(packageName, pid, uid, caller, id);
1119 } catch (RemoteException e) {
Gabriel Pealf0593bc2014-07-22 09:39:06 -07001120 Slog.e(TAG, "Remote failure in skipToTrack", e);
1121 }
1122 }
1123
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001124 public void pause(String packageName, int pid, int uid, ISessionControllerCallback caller) {
RoboErik8ae0f342014-02-24 18:02:08 -08001125 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001126 mCb.onPause(packageName, pid, uid, caller);
1127 } catch (RemoteException e) {
RoboErik8ae0f342014-02-24 18:02:08 -08001128 Slog.e(TAG, "Remote failure in pause.", e);
1129 }
1130 }
1131
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001132 public void stop(String packageName, int pid, int uid, ISessionControllerCallback caller) {
RoboErik8ae0f342014-02-24 18:02:08 -08001133 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001134 mCb.onStop(packageName, pid, uid, caller);
1135 } catch (RemoteException e) {
RoboErik8ae0f342014-02-24 18:02:08 -08001136 Slog.e(TAG, "Remote failure in stop.", e);
1137 }
1138 }
1139
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001140 public void next(String packageName, int pid, int uid, ISessionControllerCallback caller) {
RoboErik8ae0f342014-02-24 18:02:08 -08001141 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001142 mCb.onNext(packageName, pid, uid, caller);
1143 } catch (RemoteException e) {
RoboErik8ae0f342014-02-24 18:02:08 -08001144 Slog.e(TAG, "Remote failure in next.", e);
1145 }
1146 }
1147
Jaewan Kim21c23e32018-05-17 16:47:31 +09001148 public void previous(String packageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001149 ISessionControllerCallback caller) {
RoboErik8ae0f342014-02-24 18:02:08 -08001150 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001151 mCb.onPrevious(packageName, pid, uid, caller);
1152 } catch (RemoteException e) {
RoboErik8ae0f342014-02-24 18:02:08 -08001153 Slog.e(TAG, "Remote failure in previous.", e);
1154 }
1155 }
1156
Jaewan Kim21c23e32018-05-17 16:47:31 +09001157 public void fastForward(String packageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001158 ISessionControllerCallback caller) {
RoboErik8ae0f342014-02-24 18:02:08 -08001159 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001160 mCb.onFastForward(packageName, pid, uid, caller);
1161 } catch (RemoteException e) {
RoboErik8ae0f342014-02-24 18:02:08 -08001162 Slog.e(TAG, "Remote failure in fastForward.", e);
1163 }
1164 }
1165
Jaewan Kim21c23e32018-05-17 16:47:31 +09001166 public void rewind(String packageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001167 ISessionControllerCallback caller) {
RoboErik8ae0f342014-02-24 18:02:08 -08001168 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001169 mCb.onRewind(packageName, pid, uid, caller);
1170 } catch (RemoteException e) {
RoboErik8ae0f342014-02-24 18:02:08 -08001171 Slog.e(TAG, "Remote failure in rewind.", e);
1172 }
1173 }
1174
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001175 public void seekTo(String packageName, int pid, int uid, ISessionControllerCallback caller,
Jaewan Kim21c23e32018-05-17 16:47:31 +09001176 long pos) {
RoboErik8ae0f342014-02-24 18:02:08 -08001177 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001178 mCb.onSeekTo(packageName, pid, uid, caller, pos);
1179 } catch (RemoteException e) {
RoboErik8ae0f342014-02-24 18:02:08 -08001180 Slog.e(TAG, "Remote failure in seekTo.", e);
1181 }
1182 }
1183
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001184 public void rate(String packageName, int pid, int uid, ISessionControllerCallback caller,
Jaewan Kim21c23e32018-05-17 16:47:31 +09001185 Rating rating) {
RoboErik8ae0f342014-02-24 18:02:08 -08001186 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001187 mCb.onRate(packageName, pid, uid, caller, rating);
1188 } catch (RemoteException e) {
RoboErik8ae0f342014-02-24 18:02:08 -08001189 Slog.e(TAG, "Remote failure in rate.", e);
1190 }
1191 }
RoboErikb69ffd42014-05-30 14:57:59 -07001192
Hyundo Moon04fb2e72019-02-12 15:32:15 +09001193 public void setPlaybackSpeed(String packageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001194 ISessionControllerCallback caller, float speed) {
Hyundo Moon04fb2e72019-02-12 15:32:15 +09001195 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001196 mCb.onSetPlaybackSpeed(packageName, pid, uid, caller, speed);
1197 } catch (RemoteException e) {
Hyundo Moon04fb2e72019-02-12 15:32:15 +09001198 Slog.e(TAG, "Remote failure in setPlaybackSpeed.", e);
1199 }
1200 }
1201
Jaewan Kim21c23e32018-05-17 16:47:31 +09001202 public void adjustVolume(String packageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001203 ISessionControllerCallback caller, boolean asSystemService, int direction) {
RoboErikb69ffd42014-05-30 14:57:59 -07001204 try {
Jaewan Kim77748b62018-05-03 19:43:33 +09001205 if (asSystemService) {
Hyundo Moon7969f772019-03-21 17:16:16 +09001206 mCb.onAdjustVolume(mContext.getPackageName(), Process.myPid(),
Jaewan Kim21c23e32018-05-17 16:47:31 +09001207 Process.SYSTEM_UID, null, direction);
Jaewan Kim77748b62018-05-03 19:43:33 +09001208 } else {
Hyundo Moon7969f772019-03-21 17:16:16 +09001209 mCb.onAdjustVolume(packageName, pid, uid, caller, direction);
Jaewan Kim77748b62018-05-03 19:43:33 +09001210 }
Hyundo Moon7969f772019-03-21 17:16:16 +09001211 } catch (RemoteException e) {
RoboErik1ff5b162014-07-15 17:23:18 -07001212 Slog.e(TAG, "Remote failure in adjustVolume.", e);
RoboErikb69ffd42014-05-30 14:57:59 -07001213 }
1214 }
1215
Jaewan Kim21c23e32018-05-17 16:47:31 +09001216 public void setVolumeTo(String packageName, int pid, int uid,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001217 ISessionControllerCallback caller, int value) {
RoboErikb69ffd42014-05-30 14:57:59 -07001218 try {
Hyundo Moon7969f772019-03-21 17:16:16 +09001219 mCb.onSetVolumeTo(packageName, pid, uid, caller, value);
1220 } catch (RemoteException e) {
RoboErik1ff5b162014-07-15 17:23:18 -07001221 Slog.e(TAG, "Remote failure in setVolumeTo.", e);
RoboErikb69ffd42014-05-30 14:57:59 -07001222 }
1223 }
Jaewan Kim21c23e32018-05-17 16:47:31 +09001224
1225 private Intent createMediaButtonIntent(KeyEvent keyEvent) {
1226 Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
1227 mediaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
1228 return mediaButtonIntent;
1229 }
RoboErik01fe6612014-02-13 14:19:04 -08001230 }
1231
Hyundo Moon8b1f9752019-03-14 17:44:29 +09001232 class ControllerStub extends ISessionController.Stub {
RoboErik01fe6612014-02-13 14:19:04 -08001233 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001234 public void sendCommand(String packageName, ISessionControllerCallback caller,
Jaewan Kim21c23e32018-05-17 16:47:31 +09001235 String command, Bundle args, ResultReceiver cb) {
Hyundo Moonb1e344e2018-03-22 17:22:14 +09001236 mSessionCb.sendCommand(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
Jaewan Kim21c23e32018-05-17 16:47:31 +09001237 caller, command, args, cb);
RoboErik01fe6612014-02-13 14:19:04 -08001238 }
1239
1240 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001241 public boolean sendMediaButton(String packageName, ISessionControllerCallback cb,
Jaewan Kimda593892019-01-29 16:32:55 +09001242 KeyEvent keyEvent) {
Hyundo Moonb1e344e2018-03-22 17:22:14 +09001243 return mSessionCb.sendMediaButton(packageName, Binder.getCallingPid(),
Jaewan Kimda593892019-01-29 16:32:55 +09001244 Binder.getCallingUid(), cb, false, keyEvent);
RoboErik01fe6612014-02-13 14:19:04 -08001245 }
1246
RoboErik01fe6612014-02-13 14:19:04 -08001247 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001248 public void registerCallback(String packageName, ISessionControllerCallback cb) {
RoboErik07c70772014-03-20 13:33:52 -07001249 synchronized (mLock) {
RoboErik24762bf2014-08-13 15:00:21 -07001250 // If this session is already destroyed tell the caller and
1251 // don't add them.
1252 if (mDestroyed) {
1253 try {
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001254 cb.onSessionDestroyed();
RoboErik24762bf2014-08-13 15:00:21 -07001255 } catch (Exception e) {
1256 // ignored
1257 }
1258 return;
1259 }
Jaewan Kim742e3792017-03-22 18:22:40 +09001260 if (getControllerHolderIndexForCb(cb) < 0) {
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001261 mControllerCallbackHolders.add(new ISessionControllerCallbackHolder(cb,
Jaewan Kim21c23e32018-05-17 16:47:31 +09001262 packageName, Binder.getCallingUid()));
RoboErikd3c86422014-06-16 14:00:48 -07001263 if (DEBUG) {
Jaewan Kim21c23e32018-05-17 16:47:31 +09001264 Log.d(TAG, "registering controller callback " + cb + " from controller"
1265 + packageName);
RoboErikd3c86422014-06-16 14:00:48 -07001266 }
RoboErik8ae0f342014-02-24 18:02:08 -08001267 }
RoboErik01fe6612014-02-13 14:19:04 -08001268 }
1269 }
1270
RoboErik01fe6612014-02-13 14:19:04 -08001271 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001272 public void unregisterCallback(ISessionControllerCallback cb) {
RoboErik07c70772014-03-20 13:33:52 -07001273 synchronized (mLock) {
Jaewan Kim742e3792017-03-22 18:22:40 +09001274 int index = getControllerHolderIndexForCb(cb);
RoboErikd3c86422014-06-16 14:00:48 -07001275 if (index != -1) {
Jaewan Kim742e3792017-03-22 18:22:40 +09001276 mControllerCallbackHolders.remove(index);
RoboErikd3c86422014-06-16 14:00:48 -07001277 }
1278 if (DEBUG) {
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001279 Log.d(TAG, "unregistering callback " + cb.asBinder());
RoboErikd3c86422014-06-16 14:00:48 -07001280 }
RoboErik8ae0f342014-02-24 18:02:08 -08001281 }
RoboErik01fe6612014-02-13 14:19:04 -08001282 }
1283
RoboErik01fe6612014-02-13 14:19:04 -08001284 @Override
RoboErikaa4e23b2014-07-24 18:35:11 -07001285 public String getPackageName() {
1286 return mPackageName;
1287 }
1288
1289 @Override
1290 public String getTag() {
1291 return mTag;
RoboErikfb442b02014-06-08 11:15:01 -07001292 }
1293
1294 @Override
Hyundo Moon5fc8db02019-02-20 15:51:56 +09001295 public Bundle getSessionInfo() {
1296 return mSessionInfo;
1297 }
1298
1299 @Override
RoboErike34c09d2014-07-24 10:20:41 -07001300 public PendingIntent getLaunchPendingIntent() {
1301 return mLaunchIntent;
1302 }
1303
1304 @Override
RoboErik73e23e22014-06-10 17:10:41 -07001305 public long getFlags() {
1306 return mFlags;
1307 }
1308
1309 @Override
Hyundo Moon98e81922019-01-03 19:33:05 +09001310 public PlaybackInfo getVolumeAttributes() {
Sungsoo Lim39d07a32019-01-20 13:02:01 +09001311 return MediaSessionRecord.this.getVolumeAttributes();
RoboErikef3c9e92014-06-19 16:07:28 -07001312 }
1313
1314 @Override
Jaewan Kimffdb53d2018-11-28 17:45:38 +09001315 public void adjustVolume(String packageName, String opPackageName,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001316 ISessionControllerCallback caller, int direction, int flags) {
Hyundo Moonb1e344e2018-03-22 17:22:14 +09001317 int pid = Binder.getCallingPid();
RoboErik0dac35a2014-08-12 15:48:49 -07001318 int uid = Binder.getCallingUid();
RoboErikf77b99f2014-06-27 11:38:59 -07001319 final long token = Binder.clearCallingIdentity();
1320 try {
Jaewan Kimffdb53d2018-11-28 17:45:38 +09001321 MediaSessionRecord.this.adjustVolume(packageName, opPackageName, pid, uid, caller,
Jaewan Kimda593892019-01-29 16:32:55 +09001322 false, direction, flags, false /* useSuggested */);
RoboErikf77b99f2014-06-27 11:38:59 -07001323 } finally {
1324 Binder.restoreCallingIdentity(token);
1325 }
RoboErikef3c9e92014-06-19 16:07:28 -07001326 }
1327
1328 @Override
Jaewan Kimffdb53d2018-11-28 17:45:38 +09001329 public void setVolumeTo(String packageName, String opPackageName,
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001330 ISessionControllerCallback caller, int value, int flags) {
Hyundo Moonb1e344e2018-03-22 17:22:14 +09001331 int pid = Binder.getCallingPid();
RoboErik0dac35a2014-08-12 15:48:49 -07001332 int uid = Binder.getCallingUid();
RoboErikf77b99f2014-06-27 11:38:59 -07001333 final long token = Binder.clearCallingIdentity();
1334 try {
Jaewan Kimffdb53d2018-11-28 17:45:38 +09001335 MediaSessionRecord.this.setVolumeTo(packageName, opPackageName, pid, uid, caller,
1336 value, flags);
RoboErikf77b99f2014-06-27 11:38:59 -07001337 } finally {
1338 Binder.restoreCallingIdentity(token);
1339 }
RoboErikef3c9e92014-06-19 16:07:28 -07001340 }
1341
1342 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001343 public void prepare(String packageName, ISessionControllerCallback caller) {
Jaewan Kim21c23e32018-05-17 16:47:31 +09001344 mSessionCb.prepare(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
Donghyun Cho22188f12016-02-02 17:33:18 +09001345 }
1346
1347 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001348 public void prepareFromMediaId(String packageName, ISessionControllerCallback caller,
Jaewan Kim21c23e32018-05-17 16:47:31 +09001349 String mediaId, Bundle extras) {
Hyundo Moonb1e344e2018-03-22 17:22:14 +09001350 mSessionCb.prepareFromMediaId(packageName, Binder.getCallingPid(),
Jaewan Kim21c23e32018-05-17 16:47:31 +09001351 Binder.getCallingUid(), caller, mediaId, extras);
Donghyun Cho22188f12016-02-02 17:33:18 +09001352 }
1353
1354 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001355 public void prepareFromSearch(String packageName, ISessionControllerCallback caller,
Jaewan Kim21c23e32018-05-17 16:47:31 +09001356 String query, Bundle extras) {
Hyundo Moonb1e344e2018-03-22 17:22:14 +09001357 mSessionCb.prepareFromSearch(packageName, Binder.getCallingPid(),
Jaewan Kim21c23e32018-05-17 16:47:31 +09001358 Binder.getCallingUid(), caller, query, extras);
Donghyun Cho22188f12016-02-02 17:33:18 +09001359 }
1360
1361 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001362 public void prepareFromUri(String packageName, ISessionControllerCallback caller,
Jaewan Kim21c23e32018-05-17 16:47:31 +09001363 Uri uri, Bundle extras) {
Hyundo Moonb1e344e2018-03-22 17:22:14 +09001364 mSessionCb.prepareFromUri(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
Jaewan Kim21c23e32018-05-17 16:47:31 +09001365 caller, uri, extras);
Donghyun Cho22188f12016-02-02 17:33:18 +09001366 }
1367
1368 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001369 public void play(String packageName, ISessionControllerCallback caller) {
Jaewan Kim21c23e32018-05-17 16:47:31 +09001370 mSessionCb.play(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
RoboErik8ae0f342014-02-24 18:02:08 -08001371 }
1372
1373 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001374 public void playFromMediaId(String packageName, ISessionControllerCallback caller,
Jaewan Kim21c23e32018-05-17 16:47:31 +09001375 String mediaId, Bundle extras) {
Hyundo Moonb1e344e2018-03-22 17:22:14 +09001376 mSessionCb.playFromMediaId(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
Jaewan Kim21c23e32018-05-17 16:47:31 +09001377 caller, mediaId, extras);
Gabriel Pealf0593bc2014-07-22 09:39:06 -07001378 }
1379
1380 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001381 public void playFromSearch(String packageName, ISessionControllerCallback caller,
Jaewan Kim21c23e32018-05-17 16:47:31 +09001382 String query, Bundle extras) {
Hyundo Moonb1e344e2018-03-22 17:22:14 +09001383 mSessionCb.playFromSearch(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
Jaewan Kim21c23e32018-05-17 16:47:31 +09001384 caller, query, extras);
Gabriel Pealf0593bc2014-07-22 09:39:06 -07001385 }
1386
1387 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001388 public void playFromUri(String packageName, ISessionControllerCallback caller,
Jaewan Kim21c23e32018-05-17 16:47:31 +09001389 Uri uri, Bundle extras) {
Hyundo Moonb1e344e2018-03-22 17:22:14 +09001390 mSessionCb.playFromUri(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
Jaewan Kim21c23e32018-05-17 16:47:31 +09001391 caller, uri, extras);
P.Y. Laligandc2045472015-03-25 14:51:50 -07001392 }
1393
1394 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001395 public void skipToQueueItem(String packageName, ISessionControllerCallback caller,
Jaewan Kim21c23e32018-05-17 16:47:31 +09001396 long id) {
1397 mSessionCb.skipToTrack(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
1398 caller, id);
Gabriel Pealf0593bc2014-07-22 09:39:06 -07001399 }
1400
Gabriel Pealf0593bc2014-07-22 09:39:06 -07001401 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001402 public void pause(String packageName, ISessionControllerCallback caller) {
Jaewan Kim21c23e32018-05-17 16:47:31 +09001403 mSessionCb.pause(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
RoboErik8ae0f342014-02-24 18:02:08 -08001404 }
1405
1406 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001407 public void stop(String packageName, ISessionControllerCallback caller) {
Jaewan Kim21c23e32018-05-17 16:47:31 +09001408 mSessionCb.stop(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
RoboErik8ae0f342014-02-24 18:02:08 -08001409 }
1410
1411 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001412 public void next(String packageName, ISessionControllerCallback caller) {
Jaewan Kim21c23e32018-05-17 16:47:31 +09001413 mSessionCb.next(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
RoboErik8ae0f342014-02-24 18:02:08 -08001414 }
1415
1416 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001417 public void previous(String packageName, ISessionControllerCallback caller) {
Jaewan Kim21c23e32018-05-17 16:47:31 +09001418 mSessionCb.previous(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
1419 caller);
RoboErik8ae0f342014-02-24 18:02:08 -08001420 }
1421
1422 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001423 public void fastForward(String packageName, ISessionControllerCallback caller) {
Jaewan Kim21c23e32018-05-17 16:47:31 +09001424 mSessionCb.fastForward(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
1425 caller);
RoboErik8ae0f342014-02-24 18:02:08 -08001426 }
1427
1428 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001429 public void rewind(String packageName, ISessionControllerCallback caller) {
Jaewan Kim21c23e32018-05-17 16:47:31 +09001430 mSessionCb.rewind(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
RoboErik8ae0f342014-02-24 18:02:08 -08001431 }
1432
1433 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001434 public void seekTo(String packageName, ISessionControllerCallback caller, long pos) {
Jaewan Kim21c23e32018-05-17 16:47:31 +09001435 mSessionCb.seekTo(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller,
1436 pos);
RoboErik8ae0f342014-02-24 18:02:08 -08001437 }
1438
1439 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001440 public void rate(String packageName, ISessionControllerCallback caller, Rating rating) {
Jaewan Kim21c23e32018-05-17 16:47:31 +09001441 mSessionCb.rate(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller,
1442 rating);
RoboErik8ae0f342014-02-24 18:02:08 -08001443 }
1444
Gabriel Pealf364f942014-07-22 09:39:06 -07001445 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001446 public void setPlaybackSpeed(String packageName, ISessionControllerCallback caller,
Hyundo Moon04fb2e72019-02-12 15:32:15 +09001447 float speed) {
1448 mSessionCb.setPlaybackSpeed(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
1449 caller, speed);
1450 }
1451
1452 @Override
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001453 public void sendCustomAction(String packageName, ISessionControllerCallback caller,
Jaewan Kim21c23e32018-05-17 16:47:31 +09001454 String action, Bundle args) {
Hyundo Moonb1e344e2018-03-22 17:22:14 +09001455 mSessionCb.sendCustomAction(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
Jaewan Kim21c23e32018-05-17 16:47:31 +09001456 caller, action, args);
Gabriel Pealf364f942014-07-22 09:39:06 -07001457 }
1458
RoboErik8ae0f342014-02-24 18:02:08 -08001459 @Override
1460 public MediaMetadata getMetadata() {
RoboErikdf382ca2014-09-29 13:21:47 -07001461 synchronized (mLock) {
1462 return mMetadata;
1463 }
RoboErik8ae0f342014-02-24 18:02:08 -08001464 }
1465
1466 @Override
1467 public PlaybackState getPlaybackState() {
RoboErikf1372422014-04-23 14:38:17 -07001468 return getStateWithUpdatedPosition();
RoboErik01fe6612014-02-13 14:19:04 -08001469 }
RoboErik8ae0f342014-02-24 18:02:08 -08001470
1471 @Override
Hyundo Moonbb07e9b2019-05-09 16:03:51 +09001472 public ParceledListSlice getQueue() {
RoboErikdf382ca2014-09-29 13:21:47 -07001473 synchronized (mLock) {
Hyundo Moonbb07e9b2019-05-09 16:03:51 +09001474 return mQueue == null ? null : new ParceledListSlice<>(mQueue);
RoboErikdf382ca2014-09-29 13:21:47 -07001475 }
Gabriel Pealf0593bc2014-07-22 09:39:06 -07001476 }
1477
1478 @Override
1479 public CharSequence getQueueTitle() {
1480 return mQueueTitle;
1481 }
1482
1483 @Override
1484 public Bundle getExtras() {
RoboErikdf382ca2014-09-29 13:21:47 -07001485 synchronized (mLock) {
1486 return mExtras;
1487 }
Gabriel Pealf0593bc2014-07-22 09:39:06 -07001488 }
1489
1490 @Override
RoboErik8ae0f342014-02-24 18:02:08 -08001491 public int getRatingType() {
1492 return mRatingType;
1493 }
RoboErik8ae0f342014-02-24 18:02:08 -08001494 }
1495
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001496 private class ISessionControllerCallbackHolder {
1497 private final ISessionControllerCallback mCallback;
Jaewan Kim742e3792017-03-22 18:22:40 +09001498 private final String mPackageName;
Jaewan Kim21c23e32018-05-17 16:47:31 +09001499 private final int mUid;
Jaewan Kim742e3792017-03-22 18:22:40 +09001500
Hyundo Moon4e4459b2019-03-26 19:18:45 +09001501 ISessionControllerCallbackHolder(ISessionControllerCallback callback, String packageName,
Jaewan Kim21c23e32018-05-17 16:47:31 +09001502 int uid) {
Jaewan Kim742e3792017-03-22 18:22:40 +09001503 mCallback = callback;
Jaewan Kim21c23e32018-05-17 16:47:31 +09001504 mPackageName = packageName;
1505 mUid = uid;
Jaewan Kim742e3792017-03-22 18:22:40 +09001506 }
1507 }
1508
RoboErik8ae0f342014-02-24 18:02:08 -08001509 private class MessageHandler extends Handler {
1510 private static final int MSG_UPDATE_METADATA = 1;
1511 private static final int MSG_UPDATE_PLAYBACK_STATE = 2;
Gabriel Pealf0593bc2014-07-22 09:39:06 -07001512 private static final int MSG_UPDATE_QUEUE = 3;
1513 private static final int MSG_UPDATE_QUEUE_TITLE = 4;
1514 private static final int MSG_UPDATE_EXTRAS = 5;
1515 private static final int MSG_SEND_EVENT = 6;
1516 private static final int MSG_UPDATE_SESSION_STATE = 7;
1517 private static final int MSG_UPDATE_VOLUME = 8;
Sungsoo3e5a34e2017-04-04 13:35:24 +09001518 private static final int MSG_DESTROYED = 9;
RoboErik8ae0f342014-02-24 18:02:08 -08001519
1520 public MessageHandler(Looper looper) {
1521 super(looper);
1522 }
1523 @Override
1524 public void handleMessage(Message msg) {
1525 switch (msg.what) {
1526 case MSG_UPDATE_METADATA:
1527 pushMetadataUpdate();
1528 break;
1529 case MSG_UPDATE_PLAYBACK_STATE:
1530 pushPlaybackStateUpdate();
1531 break;
Gabriel Pealf0593bc2014-07-22 09:39:06 -07001532 case MSG_UPDATE_QUEUE:
1533 pushQueueUpdate();
1534 break;
1535 case MSG_UPDATE_QUEUE_TITLE:
1536 pushQueueTitleUpdate();
1537 break;
1538 case MSG_UPDATE_EXTRAS:
1539 pushExtrasUpdate();
1540 break;
RoboErik8ae0f342014-02-24 18:02:08 -08001541 case MSG_SEND_EVENT:
1542 pushEvent((String) msg.obj, msg.getData());
1543 break;
RoboErika8f95142014-05-05 14:23:49 -07001544 case MSG_UPDATE_SESSION_STATE:
1545 // TODO add session state
1546 break;
RoboErik19c95182014-06-23 15:38:48 -07001547 case MSG_UPDATE_VOLUME:
1548 pushVolumeUpdate();
1549 break;
RoboErik24762bf2014-08-13 15:00:21 -07001550 case MSG_DESTROYED:
1551 pushSessionDestroyed();
RoboErik8ae0f342014-02-24 18:02:08 -08001552 }
1553 }
1554
1555 public void post(int what) {
1556 post(what, null);
1557 }
1558
1559 public void post(int what, Object obj) {
1560 obtainMessage(what, obj).sendToTarget();
1561 }
1562
1563 public void post(int what, Object obj, Bundle data) {
1564 Message msg = obtainMessage(what, obj);
1565 msg.setData(data);
1566 msg.sendToTarget();
1567 }
RoboErik01fe6612014-02-13 14:19:04 -08001568 }
1569
1570}