• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 
17 package com.android.bluetooth.avrcpcontroller;
18 
19 import android.media.MediaMetadata;
20 import android.media.session.PlaybackState;
21 import android.os.SystemClock;
22 import android.util.Log;
23 
24 import java.util.Arrays;
25 
26 /*
27  * Contains information about remote player
28  */
29 class AvrcpPlayer {
30     private static final String TAG = "AvrcpPlayer";
31     private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
32 
33     public static final int INVALID_ID = -1;
34 
35     public static final int FEATURE_PLAY = 40;
36     public static final int FEATURE_STOP = 41;
37     public static final int FEATURE_PAUSE = 42;
38     public static final int FEATURE_REWIND = 44;
39     public static final int FEATURE_FAST_FORWARD = 45;
40     public static final int FEATURE_FORWARD = 47;
41     public static final int FEATURE_PREVIOUS = 48;
42     public static final int FEATURE_BROWSING = 59;
43 
44     private int mPlayStatus = PlaybackState.STATE_NONE;
45     private long mPlayTime = PlaybackState.PLAYBACK_POSITION_UNKNOWN;
46     private long mPlayTimeUpdate = 0;
47     private float mPlaySpeed = 1;
48     private int mId;
49     private String mName = "";
50     private int mPlayerType;
51     private byte[] mPlayerFeatures;
52     private long mAvailableActions;
53     private MediaMetadata mCurrentTrack;
54     private PlaybackState mPlaybackState;
55 
AvrcpPlayer()56     AvrcpPlayer() {
57         mId = INVALID_ID;
58         //Set Default Actions in case Player data isn't available.
59         mAvailableActions = PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_PLAY
60                 | PlaybackState.ACTION_SKIP_TO_NEXT | PlaybackState.ACTION_SKIP_TO_PREVIOUS
61                 | PlaybackState.ACTION_STOP;
62         PlaybackState.Builder playbackStateBuilder = new PlaybackState.Builder()
63                 .setActions(mAvailableActions);
64         mPlaybackState = playbackStateBuilder.build();
65     }
66 
AvrcpPlayer(int id, String name, byte[] playerFeatures, int playStatus, int playerType)67     AvrcpPlayer(int id, String name, byte[] playerFeatures, int playStatus, int playerType) {
68         mId = id;
69         mName = name;
70         mPlayStatus = playStatus;
71         mPlayerType = playerType;
72         mPlayerFeatures = Arrays.copyOf(playerFeatures, playerFeatures.length);
73         updateAvailableActions();
74         PlaybackState.Builder playbackStateBuilder = new PlaybackState.Builder()
75                 .setActions(mAvailableActions);
76         mPlaybackState = playbackStateBuilder.build();
77     }
78 
getId()79     public int getId() {
80         return mId;
81     }
82 
getName()83     public String getName() {
84         return mName;
85     }
86 
setPlayTime(int playTime)87     public void setPlayTime(int playTime) {
88         mPlayTime = playTime;
89         mPlayTimeUpdate = SystemClock.elapsedRealtime();
90         mPlaybackState = new PlaybackState.Builder(mPlaybackState).setState(mPlayStatus, mPlayTime,
91                 mPlaySpeed).build();
92     }
93 
getPlayTime()94     public long getPlayTime() {
95         return mPlayTime;
96     }
97 
setPlayStatus(int playStatus)98     public void setPlayStatus(int playStatus) {
99         mPlayTime += mPlaySpeed * (SystemClock.elapsedRealtime()
100                 - mPlaybackState.getLastPositionUpdateTime());
101         mPlayStatus = playStatus;
102         switch (mPlayStatus) {
103             case PlaybackState.STATE_STOPPED:
104                 mPlaySpeed = 0;
105                 break;
106             case PlaybackState.STATE_PLAYING:
107                 mPlaySpeed = 1;
108                 break;
109             case PlaybackState.STATE_PAUSED:
110                 mPlaySpeed = 0;
111                 break;
112             case PlaybackState.STATE_FAST_FORWARDING:
113                 mPlaySpeed = 3;
114                 break;
115             case PlaybackState.STATE_REWINDING:
116                 mPlaySpeed = -3;
117                 break;
118         }
119 
120         mPlaybackState = new PlaybackState.Builder(mPlaybackState).setState(mPlayStatus, mPlayTime,
121                 mPlaySpeed).build();
122     }
123 
getPlayStatus()124     public int getPlayStatus() {
125         return mPlayStatus;
126     }
127 
supportsFeature(int featureId)128     public boolean supportsFeature(int featureId) {
129         int byteNumber = featureId / 8;
130         byte bitMask = (byte) (1 << (featureId % 8));
131         return (mPlayerFeatures[byteNumber] & bitMask) == bitMask;
132     }
133 
getPlaybackState()134     public PlaybackState getPlaybackState() {
135         if (DBG) {
136             Log.d(TAG, "getPlayBackState state " + mPlayStatus + " time " + mPlayTime);
137         }
138         return mPlaybackState;
139     }
140 
updateCurrentTrack(MediaMetadata update)141     public synchronized void updateCurrentTrack(MediaMetadata update) {
142         if (update != null) {
143             long trackNumber = update.getLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER);
144             mPlaybackState = new PlaybackState.Builder(mPlaybackState).setActiveQueueItemId(
145                     trackNumber - 1).build();
146         }
147         mCurrentTrack = update;
148     }
149 
getCurrentTrack()150     public synchronized MediaMetadata getCurrentTrack() {
151         return mCurrentTrack;
152     }
153 
updateAvailableActions()154     private void updateAvailableActions() {
155         if (supportsFeature(FEATURE_PLAY)) {
156             mAvailableActions = mAvailableActions | PlaybackState.ACTION_PLAY;
157         }
158         if (supportsFeature(FEATURE_STOP)) {
159             mAvailableActions = mAvailableActions | PlaybackState.ACTION_STOP;
160         }
161         if (supportsFeature(FEATURE_PAUSE)) {
162             mAvailableActions = mAvailableActions | PlaybackState.ACTION_PAUSE;
163         }
164         if (supportsFeature(FEATURE_REWIND)) {
165             mAvailableActions = mAvailableActions | PlaybackState.ACTION_REWIND;
166         }
167         if (supportsFeature(FEATURE_FAST_FORWARD)) {
168             mAvailableActions = mAvailableActions | PlaybackState.ACTION_FAST_FORWARD;
169         }
170         if (supportsFeature(FEATURE_FORWARD)) {
171             mAvailableActions = mAvailableActions | PlaybackState.ACTION_SKIP_TO_NEXT;
172         }
173         if (supportsFeature(FEATURE_PREVIOUS)) {
174             mAvailableActions = mAvailableActions | PlaybackState.ACTION_SKIP_TO_PREVIOUS;
175         }
176         if (DBG) Log.d(TAG, "Supported Actions = " + mAvailableActions);
177     }
178 }
179