MediaSessionRecord.java revision 01fe661ae5da3739215d93922412df4b24c859a2
1/*
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
19import android.content.Intent;
20import android.media.IMediaController;
21import android.media.IMediaControllerCallback;
22import android.media.IMediaSession;
23import android.media.IMediaSessionCallback;
24import android.media.RemoteControlClient;
25import android.os.Bundle;
26import android.os.IBinder;
27import android.os.RemoteException;
28import android.util.Log;
29import android.view.KeyEvent;
30
31import java.util.ArrayList;
32
33/**
34 * This is the system implementation of a Session. Apps will interact with the
35 * MediaSession wrapper class instead.
36 */
37public class MediaSessionRecord implements IBinder.DeathRecipient {
38    private static final String TAG = "MediaSessionImpl";
39
40    private final int mPid;
41    private final String mPackageName;
42    private final String mTag;
43    private final ControllerStub mController;
44    private final SessionStub mSession;
45    private final SessionCb mSessionCb;
46    private final MediaSessionService mService;
47
48    private final ArrayList<IMediaControllerCallback> mSessionCallbacks =
49            new ArrayList<IMediaControllerCallback>();
50
51    private int mPlaybackState = RemoteControlClient.PLAYSTATE_NONE;
52
53    public MediaSessionRecord(int pid, String packageName, IMediaSessionCallback cb, String tag,
54            MediaSessionService service) {
55        mPid = pid;
56        mPackageName = packageName;
57        mTag = tag;
58        mController = new ControllerStub();
59        mSession = new SessionStub();
60        mSessionCb = new SessionCb(cb);
61        mService = service;
62    }
63
64    public IMediaSession getSessionBinder() {
65        return mSession;
66    }
67
68    public IMediaController getControllerBinder() {
69        return mController;
70    }
71
72    public void setPlaybackStateInternal(int state) {
73        mPlaybackState = state;
74        for (int i = mSessionCallbacks.size() - 1; i >= 0; i--) {
75            IMediaControllerCallback cb = mSessionCallbacks.get(i);
76            try {
77                cb.onPlaybackUpdate(state);
78            } catch (RemoteException e) {
79                Log.d(TAG, "SessionCallback object dead in setPlaybackState.", e);
80                mSessionCallbacks.remove(i);
81            }
82        }
83    }
84
85    @Override
86    public void binderDied() {
87        mService.sessionDied(this);
88    }
89
90    private void onDestroy() {
91        mService.destroySession(this);
92    }
93
94    private final class SessionStub extends IMediaSession.Stub {
95
96        @Override
97        public void setPlaybackState(int state) throws RemoteException {
98            setPlaybackStateInternal(state);
99        }
100
101        @Override
102        public void destroy() throws RemoteException {
103            onDestroy();
104        }
105
106        @Override
107        public void sendEvent(Bundle data) throws RemoteException {
108        }
109
110        @Override
111        public IMediaController getMediaSessionToken() throws RemoteException {
112            return mController;
113        }
114
115        @Override
116        public void setMetadata(Bundle metadata) throws RemoteException {
117        }
118
119        @Override
120        public void setRouteState(Bundle routeState) throws RemoteException {
121        }
122
123        @Override
124        public void setRoute(Bundle medaiRouteDescriptor) throws RemoteException {
125        }
126
127    }
128
129    class SessionCb {
130        private final IMediaSessionCallback mCb;
131
132        public SessionCb(IMediaSessionCallback cb) {
133            mCb = cb;
134        }
135
136        public void sendMediaButton(KeyEvent keyEvent) {
137            Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
138            mediaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
139            try {
140                mCb.onMediaButton(mediaButtonIntent);
141            } catch (RemoteException e) {
142                Log.d(TAG, "Controller object dead in sendMediaRequest.", e);
143                onDestroy();
144            }
145        }
146
147        public void sendCommand(String command, Bundle extras) {
148            try {
149                mCb.onCommand(command, extras);
150            } catch (RemoteException e) {
151                Log.d(TAG, "Controller object dead in sendCommand.", e);
152                onDestroy();
153            }
154        }
155
156        public void registerCallbackListener(IMediaSessionCallback cb) {
157
158        }
159
160    }
161
162    class ControllerStub extends IMediaController.Stub {
163        /*
164         */
165        @Override
166        public void sendCommand(String command, Bundle extras) throws RemoteException {
167            mSessionCb.sendCommand(command, extras);
168        }
169
170        @Override
171        public void sendMediaButton(KeyEvent mediaButtonIntent) {
172            mSessionCb.sendMediaButton(mediaButtonIntent);
173        }
174
175        /*
176         */
177        @Override
178        public void registerCallbackListener(IMediaControllerCallback cb) throws RemoteException {
179            if (!mSessionCallbacks.contains(cb)) {
180                mSessionCallbacks.add(cb);
181            }
182        }
183
184        /*
185         */
186        @Override
187        public void unregisterCallbackListener(IMediaControllerCallback cb)
188                throws RemoteException {
189            mSessionCallbacks.remove(cb);
190        }
191
192        /*
193         */
194        @Override
195        public int getPlaybackState() throws RemoteException {
196            return mPlaybackState;
197        }
198    }
199
200}
201