Android-x86
Fork
Spenden

  • R/O
  • HTTP
  • SSH
  • HTTPS

packages-apps-Bluetooth: Commit

packages/apps/Bluetooth


Commit MetaInfo

Revision1ab97a2f4868aeb050cc0eae6e3a22081af69f05 (tree)
Zeit2017-06-24 10:24:59
AutorMarie Janssen <jamuraa@goog...>
Commiterandroid-build-team Robot

Log Message

Avrcp: Limit available players changed

According to the spec, we should only send an Available Players Changed
update when a player is added or removed. (AVRCP 1.6.1 Sec 6.9.4 p74)

Only send an update when a player is added or removed. If a player
would change feature bits, display name, major or minor type, present it
as a new player instead and remove the old player.

Sync available players notifications with other notifications.

Bug: 34471252
Test: switch players, note that Available Players Changed is not sent
all the time
Change-Id: Icd3730afa6e182810920f28fa7db17b98e53ceea
(cherry picked from commit f2f6a4ea02e9456f71ea0490112845110ca5d975)
(cherry picked from commit 85ff6903243d244d4342f390bb40aa99097a9a7c)

Ändern Zusammenfassung

Diff

--- a/src/com/android/bluetooth/avrcp/Avrcp.java
+++ b/src/com/android/bluetooth/avrcp/Avrcp.java
@@ -161,9 +161,8 @@ public final class Avrcp {
161161 private static final int MSG_SET_ABSOLUTE_VOLUME = 16;
162162 private static final int MSG_ABS_VOL_TIMEOUT = 17;
163163 private static final int MSG_SET_A2DP_AUDIO_STATE = 18;
164- private static final int MSG_AVAILABLE_PLAYERS_CHANGED_RSP = 19;
165- private static final int MSG_NOW_PLAYING_CHANGED_RSP = 20;
166- private static final int MSG_UPDATE_MEDIA = 21;
164+ private static final int MSG_NOW_PLAYING_CHANGED_RSP = 19;
165+ private static final int MSG_UPDATE_MEDIA = 20;
167166
168167 private static final int CMD_TIMEOUT_DELAY = 2000;
169168 private static final int MEDIA_DWELL_TIME = 1000;
@@ -179,6 +178,7 @@ public final class Avrcp {
179178
180179 /* List of Media player instances, useful for retrieving MediaPlayerList or MediaPlayerInfo */
181180 private SortedMap<Integer, MediaPlayerInfo> mMediaPlayerInfoList;
181+ private boolean mAvailablePlayerViewChanged;
182182
183183 /* List of media players which supports browse */
184184 private List<BrowsePlayerInfo> mBrowsePlayerInfoList;
@@ -304,6 +304,7 @@ public final class Avrcp {
304304 mMediaControllerCb = new MediaControllerListener();
305305 mAvrcpMediaRsp = new AvrcpMediaRsp();
306306 mMediaPlayerInfoList = new TreeMap<Integer, MediaPlayerInfo>();
307+ mAvailablePlayerViewChanged = false;
307308 mBrowsePlayerInfoList = Collections.synchronizedList(new ArrayList<BrowsePlayerInfo>());
308309 mPassthroughDispatched = 0;
309310 mPassthroughLogs = new EvictingQueue<MediaKeyLog>(PASSTHROUGH_LOG_MAX_SIZE);
@@ -474,13 +475,6 @@ public final class Avrcp {
474475 processRegisterNotification((byte[]) msg.obj, msg.arg1, msg.arg2);
475476 break;
476477
477- case MSG_AVAILABLE_PLAYERS_CHANGED_RSP:
478- if (DEBUG) Log.v(TAG, "MSG_AVAILABLE_PLAYERS_CHANGED_RSP");
479- removeMessages(MSG_AVAILABLE_PLAYERS_CHANGED_RSP);
480- registerNotificationRspAvalPlayerChangedNative(
481- AvrcpConstants.NOTIFICATION_TYPE_CHANGED);
482- break;
483-
484478 case MSG_NOW_PLAYING_CHANGED_RSP:
485479 if (DEBUG) Log.v(TAG, "MSG_NOW_PLAYING_CHANGED_RSP");
486480 removeMessages(MSG_NOW_PLAYING_CHANGED_RSP);
@@ -986,19 +980,27 @@ public final class Avrcp {
986980 }
987981
988982 private void updateCurrentMediaState(boolean registering) {
989- if (!registering && mAddrPlayerChangedNT == AvrcpConstants.NOTIFICATION_TYPE_INTERIM
990- && mReportedPlayerID != mCurrAddrPlayerID) {
991- registerNotificationRspAddrPlayerChangedNative(
992- AvrcpConstants.NOTIFICATION_TYPE_CHANGED, mCurrAddrPlayerID, sUIDCounter);
993- mAddrPlayerChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
994- // Changing player sends reject to all these, so disable them.
995- mReportedPlayerID = mCurrAddrPlayerID;
996- mPlayStatusChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
997- mTrackChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
998- mPlayPosChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
999- // If the player changed, they need to re-request anything here again
1000- // so we can skip the rest of the update.
1001- return;
983+ // Only do player updates when we aren't registering for track changes.
984+ if (!registering) {
985+ if (mAvailablePlayerViewChanged) {
986+ registerNotificationRspAvalPlayerChangedNative(
987+ AvrcpConstants.NOTIFICATION_TYPE_CHANGED);
988+ mAvailablePlayerViewChanged = false;
989+ }
990+ if (mAddrPlayerChangedNT == AvrcpConstants.NOTIFICATION_TYPE_INTERIM
991+ && mReportedPlayerID != mCurrAddrPlayerID) {
992+ registerNotificationRspAddrPlayerChangedNative(
993+ AvrcpConstants.NOTIFICATION_TYPE_CHANGED, mCurrAddrPlayerID, sUIDCounter);
994+ mAddrPlayerChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
995+ // Changing player sends reject to anything else we would notify...
996+ mReportedPlayerID = mCurrAddrPlayerID;
997+ mPlayStatusChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
998+ mTrackChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
999+ mPlayPosChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
1000+ // If the player changed, they need to re-request anything here again
1001+ // so we can skip the rest of the update.
1002+ return;
1003+ }
10021004 }
10031005
10041006 MediaAttributes currentAttributes;
@@ -1580,23 +1582,17 @@ public final class Avrcp {
15801582 @Override
15811583 public void onActiveSessionsChanged(
15821584 List<android.media.session.MediaController> newControllers) {
1583- boolean playersChanged = false;
1584-
15851585 // Update the current players
15861586 for (android.media.session.MediaController controller : newControllers) {
15871587 addMediaPlayerController(controller);
1588- playersChanged = true;
15891588 }
15901589
1591- if (playersChanged) {
1592- mHandler.sendEmptyMessage(MSG_AVAILABLE_PLAYERS_CHANGED_RSP);
1593- if (newControllers.size() > 0 && getAddressedPlayerInfo() == null) {
1594- if (DEBUG)
1595- Log.v(TAG,
1596- "No addressed player but active sessions, taking first.");
1597- setAddressedMediaSessionPackage(newControllers.get(0).getPackageName());
1598- }
1590+ if (newControllers.size() > 0 && getAddressedPlayerInfo() == null) {
1591+ if (DEBUG)
1592+ Log.v(TAG, "No addressed player but active sessions, taking first.");
1593+ setAddressedMediaSessionPackage(newControllers.get(0).getPackageName());
15991594 }
1595+ scheduleMediaUpdate();
16001596 }
16011597 };
16021598
@@ -1612,7 +1608,7 @@ public final class Avrcp {
16121608 // If the player doesn't exist, we need to add it.
16131609 if (getMediaPlayerInfo(packageName) == null) {
16141610 addMediaPlayerPackage(packageName);
1615- mHandler.sendEmptyMessage(MSG_AVAILABLE_PLAYERS_CHANGED_RSP);
1611+ scheduleMediaUpdate();
16161612 }
16171613 synchronized (mMediaPlayerInfoList) {
16181614 for (Map.Entry<Integer, MediaPlayerInfo> entry : mMediaPlayerInfoList.entrySet()) {
@@ -1758,9 +1754,8 @@ public final class Avrcp {
17581754 for (android.media.session.MediaController controller : controllers) {
17591755 addMediaPlayerController(controller);
17601756 }
1761- if (controllers.size() > 0) {
1762- mHandler.sendEmptyMessage(MSG_AVAILABLE_PLAYERS_CHANGED_RSP);
1763- }
1757+
1758+ scheduleMediaUpdate();
17641759
17651760 if (mMediaPlayerInfoList.size() > 0) {
17661761 // Set the first one as the Addressed Player
@@ -1808,10 +1803,20 @@ public final class Avrcp {
18081803 private boolean addMediaPlayerInfo(MediaPlayerInfo info) {
18091804 int updateId = -1;
18101805 boolean updated = false;
1806+ boolean currentRemoved = false;
18111807 synchronized (mMediaPlayerInfoList) {
18121808 for (Map.Entry<Integer, MediaPlayerInfo> entry : mMediaPlayerInfoList.entrySet()) {
1813- if (info.getPackageName().equals(entry.getValue().getPackageName())) {
1814- updateId = entry.getKey();
1809+ MediaPlayerInfo current = entry.getValue();
1810+ int id = entry.getKey();
1811+ if (info.getPackageName().equals(current.getPackageName())) {
1812+ if (!current.equalView(info)) {
1813+ // If we would present a different player, make it a new player
1814+ // so that controllers know whether a player is browsable or not.
1815+ mMediaPlayerInfoList.remove(id);
1816+ currentRemoved = (mCurrAddrPlayerID == id);
1817+ break;
1818+ }
1819+ updateId = id;
18151820 updated = true;
18161821 break;
18171822 }
@@ -1820,12 +1825,13 @@ public final class Avrcp {
18201825 // New player
18211826 mLastUsedPlayerID++;
18221827 updateId = mLastUsedPlayerID;
1828+ mAvailablePlayerViewChanged = true;
18231829 }
18241830 mMediaPlayerInfoList.put(updateId, info);
18251831 if (DEBUG)
18261832 Log.d(TAG, (updated ? "update #" : "add #") + updateId + ":" + info.toString());
1827- if (updateId == mCurrAddrPlayerID) {
1828- updateCurrentController(mCurrAddrPlayerID, mCurrBrowsePlayerID);
1833+ if (currentRemoved || updateId == mCurrAddrPlayerID) {
1834+ updateCurrentController(updateId, mCurrBrowsePlayerID);
18291835 }
18301836 }
18311837 return updated;
@@ -1844,6 +1850,7 @@ public final class Avrcp {
18441850 if (removeKey != -1) {
18451851 if (DEBUG)
18461852 Log.d(TAG, "remove #" + removeKey + ":" + mMediaPlayerInfoList.get(removeKey));
1853+ mAvailablePlayerViewChanged = true;
18471854 return mMediaPlayerInfoList.remove(removeKey);
18481855 }
18491856
--- a/src/com/android/bluetooth/avrcp/AvrcpHelperClasses.java
+++ b/src/com/android/bluetooth/avrcp/AvrcpHelperClasses.java
@@ -16,6 +16,8 @@
1616
1717 package com.android.bluetooth.avrcp;
1818
19+import android.annotation.NonNull;
20+import android.annotation.Nullable;
1921 import android.media.session.MediaSession;
2022
2123 import com.android.bluetooth.Utils;
@@ -200,17 +202,19 @@ class MediaPlayerInfo {
200202 private int subType;
201203 private byte playStatus;
202204 private short[] featureBitMask;
203- private String packageName;
204- private String displayableName;
205- private MediaController mediaController;
205+ private @NonNull String packageName;
206+ private @NonNull String displayableName;
207+ private @Nullable MediaController mediaController;
206208
207- MediaPlayerInfo(MediaController controller, byte majorType, int subType, byte playStatus,
208- short[] featureBitMask, String packageName, String displayableName) {
209+ MediaPlayerInfo(@Nullable MediaController controller, byte majorType, int subType,
210+ byte playStatus, short[] featureBitMask, @NonNull String packageName,
211+ @Nullable String displayableName) {
209212 this.setMajorType(majorType);
210213 this.setSubType(subType);
211214 this.playStatus = playStatus;
212215 // store a copy the FeatureBitMask array
213216 this.featureBitMask = Arrays.copyOf(featureBitMask, featureBitMask.length);
217+ Arrays.sort(this.featureBitMask);
214218 this.setPackageName(packageName);
215219 this.setDisplayableName(displayableName);
216220 this.setMediaController(controller);
@@ -236,7 +240,7 @@ class MediaPlayerInfo {
236240 this.mediaController = mediaController;
237241 }
238242
239- void setPackageName(String name) {
243+ void setPackageName(@NonNull String name) {
240244 // Controller determines package name when it is set.
241245 if (mediaController != null) return;
242246 this.packageName = name;
@@ -271,7 +275,8 @@ class MediaPlayerInfo {
271275 return displayableName;
272276 }
273277
274- void setDisplayableName(String displayableName) {
278+ void setDisplayableName(@Nullable String displayableName) {
279+ if (displayableName == null) displayableName = "";
275280 this.displayableName = displayableName;
276281 }
277282
@@ -282,6 +287,7 @@ class MediaPlayerInfo {
282287 void setFeatureBitMask(short[] featureBitMask) {
283288 synchronized (this) {
284289 this.featureBitMask = Arrays.copyOf(featureBitMask, featureBitMask.length);
290+ Arrays.sort(this.featureBitMask);
285291 }
286292 }
287293
@@ -295,6 +301,14 @@ class MediaPlayerInfo {
295301 return false;
296302 }
297303
304+ /** Tests if the view of this player presented to the controller is different enough to
305+ * justify sending an Available Players Changed update */
306+ public boolean equalView(MediaPlayerInfo other) {
307+ return (this.majorType == other.getMajorType()) && (this.subType == other.getSubType())
308+ && Arrays.equals(this.featureBitMask, other.getFeatureBitMask())
309+ && this.displayableName.equals(other.getDisplayableName());
310+ }
311+
298312 @Override
299313 public String toString() {
300314 StringBuilder sb = new StringBuilder();
Show on old repository browser