Loading media/java/android/media/AudioManager.java +26 −0 Original line number Diff line number Diff line Loading @@ -2281,6 +2281,32 @@ public class AudioManager { } } /** * @hide * Controls whether a remote control display needs periodic checks of the RemoteControlClient * playback position to verify that the estimated position has not drifted from the actual * position. By default the check is not performed. * The IRemoteControlDisplay must have been previously registered for this to have any effect. * @param rcd the IRemoteControlDisplay for which the anti-drift mechanism will be enabled * or disabled. No effect is null. * @param wantsSync if true, RemoteControlClient instances which expose their playback position * to the framework will regularly compare the estimated playback position with the actual * position, and will update the IRemoteControlDisplay implementation whenever a drift is * detected. */ public void remoteControlDisplayWantsPlaybackPositionSync(IRemoteControlDisplay rcd, boolean wantsSync) { if (rcd == null) { return; } IAudioService service = getService(); try { service.remoteControlDisplayWantsPlaybackPositionSync(rcd, wantsSync); } catch (RemoteException e) { Log.e(TAG, "Dead object in remoteControlDisplayWantsPlaybackPositionSync " + e); } } /** * @hide * Request the user of a RemoteControlClient to seek to the given playback position. Loading media/java/android/media/AudioService.java +52 −1 Original line number Diff line number Diff line Loading @@ -5085,7 +5085,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished { final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next(); pw.println(" IRCD: " + di.mRcDisplay + " -- w:" + di.mArtworkExpectedWidth + " -- h:" + di.mArtworkExpectedHeight); " -- h:" + di.mArtworkExpectedHeight+ " -- wantsPosSync:" + di.mWantsPositionSync); } } } Loading Loading @@ -5689,6 +5690,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished { private IBinder mRcDisplayBinder; private int mArtworkExpectedWidth = -1; private int mArtworkExpectedHeight = -1; private boolean mWantsPositionSync = false; public DisplayInfoForServer(IRemoteControlDisplay rcd, int w, int h) { if (DEBUG_RC) Log.i(TAG, "new DisplayInfoForServer for " + rcd + " w=" + w + " h=" + h); Loading Loading @@ -5752,6 +5754,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished { try { rcc.plugRemoteControlDisplay(di.mRcDisplay, di.mArtworkExpectedWidth, di.mArtworkExpectedHeight); if (di.mWantsPositionSync) { rcc.setWantsSyncForDisplay(di.mRcDisplay, true); } } catch (RemoteException e) { Log.e(TAG, "Error connecting RCD to RCC in RCC registration",e); } Loading Loading @@ -5905,6 +5910,52 @@ public class AudioService extends IAudioService.Stub implements OnFinished { } } /** * Controls whether a remote control display needs periodic checks of the RemoteControlClient * playback position to verify that the estimated position has not drifted from the actual * position. By default the check is not performed. * The IRemoteControlDisplay must have been previously registered for this to have any effect. * @param rcd the IRemoteControlDisplay for which the anti-drift mechanism will be enabled * or disabled. Not null. * @param wantsSync if true, RemoteControlClient instances which expose their playback position * to the framework will regularly compare the estimated playback position with the actual * position, and will update the IRemoteControlDisplay implementation whenever a drift is * detected. */ public void remoteControlDisplayWantsPlaybackPositionSync(IRemoteControlDisplay rcd, boolean wantsSync) { synchronized(mRCStack) { boolean rcdRegistered = false; // store the information about this display // (display stack traversal order doesn't matter). final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next(); if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) { di.mWantsPositionSync = wantsSync; rcdRegistered = true; break; } } if (!rcdRegistered) { return; } // notify all current RemoteControlClients // (stack traversal order doesn't matter as we notify all RCCs) final Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator(); while (stackIterator.hasNext()) { final RemoteControlStackEntry rcse = stackIterator.next(); if (rcse.mRcClient != null) { try { rcse.mRcClient.setWantsSyncForDisplay(rcd, wantsSync); } catch (RemoteException e) { Log.e(TAG, "Error setting position sync flag for RCD on RCC: ", e); } } } } } public void setRemoteControlClientPlaybackPosition(int generationId, long timeMs) { // ignore position change requests if invalid generation ID synchronized(mRCStack) { Loading media/java/android/media/IAudioService.aidl +14 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,20 @@ interface IAudioService { * display doesn't need to receive artwork. */ oneway void remoteControlDisplayUsesBitmapSize(in IRemoteControlDisplay rcd, int w, int h); /** * Controls whether a remote control display needs periodic checks of the RemoteControlClient * playback position to verify that the estimated position has not drifted from the actual * position. By default the check is not performed. * The IRemoteControlDisplay must have been previously registered for this to have any effect. * @param rcd the IRemoteControlDisplay for which the anti-drift mechanism will be enabled * or disabled. Not null. * @param wantsSync if true, RemoteControlClient instances which expose their playback position * to the framework will regularly compare the estimated playback position with the actual * position, and will update the IRemoteControlDisplay implementation whenever a drift is * detected. */ oneway void remoteControlDisplayWantsPlaybackPositionSync(in IRemoteControlDisplay rcd, boolean wantsSync); /** * Request the user of a RemoteControlClient to seek to the given playback position. * @param generationId the RemoteControlClient generation counter for which this request is Loading media/java/android/media/IRemoteControlClient.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -47,5 +47,6 @@ oneway interface IRemoteControlClient void plugRemoteControlDisplay(IRemoteControlDisplay rcd, int w, int h); void unplugRemoteControlDisplay(IRemoteControlDisplay rcd); void setBitmapSizeForDisplay(IRemoteControlDisplay rcd, int w, int h); void setWantsSyncForDisplay(IRemoteControlDisplay rcd, boolean wantsSync); void seekTo(int clientGeneration, long timeMs); } No newline at end of file media/java/android/media/RemoteControlClient.java +89 −22 Original line number Diff line number Diff line Loading @@ -645,12 +645,21 @@ public class RemoteControlClient sendAudioServiceNewPlaybackState_syncCacheLock(); // handle automatic playback position refreshes initiateCheckForDrift_syncCacheLock(); } } } private void initiateCheckForDrift_syncCacheLock() { if (mEventHandler == null) { return; } mEventHandler.removeMessages(MSG_POSITION_DRIFT_CHECK); if (timeInMs == PLAYBACK_POSITION_INVALID) { // this playback state refresh has no known playback position, it's no use if (!mNeedsPositionSync) { return; } if (mPlaybackPositionMs < 0) { // the current playback state has no known playback position, it's no use // trying to see if there is any drift at this point // (this also bypasses this mechanism for older apps that use the old // setPlaybackState(int) API) Loading @@ -660,20 +669,18 @@ public class RemoteControlClient // playback position moving, schedule next position drift check mEventHandler.sendMessageDelayed( mEventHandler.obtainMessage(MSG_POSITION_DRIFT_CHECK), getCheckPeriodFromSpeed(playbackSpeed)); } } getCheckPeriodFromSpeed(mPlaybackSpeed)); } } private void onPositionDriftCheck() { if (DEBUG) { Log.d(TAG, "onPositionDriftCheck()"); } synchronized(mCacheLock) { if ((mEventHandler == null) || (mPositionProvider == null)) { if ((mEventHandler == null) || (mPositionProvider == null) || !mNeedsPositionSync) { return; } if ((mPlaybackPositionMs == PLAYBACK_POSITION_INVALID) || (mPlaybackSpeed == 0.0f)) { if (DEBUG) { Log.d(TAG, " no position or 0 speed, no check needed"); } if ((mPlaybackPositionMs < 0) || (mPlaybackSpeed == 0.0f)) { if (DEBUG) { Log.d(TAG, " no valid position or 0 speed, no check needed"); } return; } long estPos = mPlaybackPositionMs + (long) Loading Loading @@ -1011,6 +1018,12 @@ public class RemoteControlClient */ private final PendingIntent mRcMediaIntent; /** * Reflects whether any "plugged in" IRemoteControlDisplay has mWantsPositonSync set to true. */ // TODO consider using a ref count for IRemoteControlDisplay requiring sync instead private boolean mNeedsPositionSync = false; /** * A class to encapsulate all the information about a remote control display. * A RemoteControlClient's metadata and state may be displayed on multiple IRemoteControlDisplay Loading @@ -1020,6 +1033,7 @@ public class RemoteControlClient private IRemoteControlDisplay mRcDisplay; private int mArtworkExpectedWidth; private int mArtworkExpectedHeight; private boolean mWantsPositionSync = false; DisplayInfoForClient(IRemoteControlDisplay rcd, int w, int h) { mRcDisplay = rcd; Loading Loading @@ -1109,6 +1123,14 @@ public class RemoteControlClient } } public void setWantsSyncForDisplay(IRemoteControlDisplay rcd, boolean wantsSync) { // only post messages, we can't block here if ((mEventHandler != null) && (rcd != null)) { mEventHandler.sendMessage(mEventHandler.obtainMessage( MSG_DISPLAY_WANTS_POS_SYNC, wantsSync ? 1 : 0, 0/*arg2 ignored*/, rcd)); } } public void seekTo(int generationId, long timeMs) { // only post messages, we can't block here if (mEventHandler != null) { Loading Loading @@ -1160,6 +1182,7 @@ public class RemoteControlClient private final static int MSG_UPDATE_DISPLAY_ARTWORK_SIZE = 9; private final static int MSG_SEEK_TO = 10; private final static int MSG_POSITION_DRIFT_CHECK = 11; private final static int MSG_DISPLAY_WANTS_POS_SYNC = 12; private class EventHandler extends Handler { public EventHandler(RemoteControlClient rcc, Looper looper) { Loading Loading @@ -1210,6 +1233,9 @@ public class RemoteControlClient case MSG_POSITION_DRIFT_CHECK: onPositionDriftCheck(); break; case MSG_DISPLAY_WANTS_POS_SYNC: onDisplayWantsSync((IRemoteControlDisplay)msg.obj, msg.arg1 == 1); break; default: Log.e(TAG, "Unknown event " + msg.what + " in RemoteControlClient handler"); } Loading Loading @@ -1410,13 +1436,29 @@ public class RemoteControlClient /** pre-condition rcd != null */ private void onUnplugDisplay(IRemoteControlDisplay rcd) { synchronized(mCacheLock) { final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) { displayIterator.remove(); return; break; } } // list of RCDs has changed, reevaluate whether position check is still needed boolean oldNeedsPositionSync = mNeedsPositionSync; boolean newNeedsPositionSync = false; displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); if (di.mWantsPositionSync) { newNeedsPositionSync = true; break; } } mNeedsPositionSync = newNeedsPositionSync; if (oldNeedsPositionSync != mNeedsPositionSync) { // update needed? initiateCheckForDrift_syncCacheLock(); } } } Loading @@ -1440,6 +1482,31 @@ public class RemoteControlClient } } /** pre-condition rcd != null */ private void onDisplayWantsSync(IRemoteControlDisplay rcd, boolean wantsSync) { synchronized(mCacheLock) { boolean oldNeedsPositionSync = mNeedsPositionSync; boolean newNeedsPositionSync = false; final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); // go through the list of RCDs and for each entry, check both whether this is the RCD // that gets upated, and whether the list has one entry that wants position sync while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) { di.mWantsPositionSync = wantsSync; } if (di.mWantsPositionSync) { newNeedsPositionSync = true; } } mNeedsPositionSync = newNeedsPositionSync; if (oldNeedsPositionSync != mNeedsPositionSync) { // update needed? initiateCheckForDrift_syncCacheLock(); } } } private void onSeekTo(int generationId, long timeMs) { synchronized (mCacheLock) { if ((mCurrentClientGenId == generationId) && (mPositionUpdateListener != null)) { Loading Loading
media/java/android/media/AudioManager.java +26 −0 Original line number Diff line number Diff line Loading @@ -2281,6 +2281,32 @@ public class AudioManager { } } /** * @hide * Controls whether a remote control display needs periodic checks of the RemoteControlClient * playback position to verify that the estimated position has not drifted from the actual * position. By default the check is not performed. * The IRemoteControlDisplay must have been previously registered for this to have any effect. * @param rcd the IRemoteControlDisplay for which the anti-drift mechanism will be enabled * or disabled. No effect is null. * @param wantsSync if true, RemoteControlClient instances which expose their playback position * to the framework will regularly compare the estimated playback position with the actual * position, and will update the IRemoteControlDisplay implementation whenever a drift is * detected. */ public void remoteControlDisplayWantsPlaybackPositionSync(IRemoteControlDisplay rcd, boolean wantsSync) { if (rcd == null) { return; } IAudioService service = getService(); try { service.remoteControlDisplayWantsPlaybackPositionSync(rcd, wantsSync); } catch (RemoteException e) { Log.e(TAG, "Dead object in remoteControlDisplayWantsPlaybackPositionSync " + e); } } /** * @hide * Request the user of a RemoteControlClient to seek to the given playback position. Loading
media/java/android/media/AudioService.java +52 −1 Original line number Diff line number Diff line Loading @@ -5085,7 +5085,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished { final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next(); pw.println(" IRCD: " + di.mRcDisplay + " -- w:" + di.mArtworkExpectedWidth + " -- h:" + di.mArtworkExpectedHeight); " -- h:" + di.mArtworkExpectedHeight+ " -- wantsPosSync:" + di.mWantsPositionSync); } } } Loading Loading @@ -5689,6 +5690,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished { private IBinder mRcDisplayBinder; private int mArtworkExpectedWidth = -1; private int mArtworkExpectedHeight = -1; private boolean mWantsPositionSync = false; public DisplayInfoForServer(IRemoteControlDisplay rcd, int w, int h) { if (DEBUG_RC) Log.i(TAG, "new DisplayInfoForServer for " + rcd + " w=" + w + " h=" + h); Loading Loading @@ -5752,6 +5754,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished { try { rcc.plugRemoteControlDisplay(di.mRcDisplay, di.mArtworkExpectedWidth, di.mArtworkExpectedHeight); if (di.mWantsPositionSync) { rcc.setWantsSyncForDisplay(di.mRcDisplay, true); } } catch (RemoteException e) { Log.e(TAG, "Error connecting RCD to RCC in RCC registration",e); } Loading Loading @@ -5905,6 +5910,52 @@ public class AudioService extends IAudioService.Stub implements OnFinished { } } /** * Controls whether a remote control display needs periodic checks of the RemoteControlClient * playback position to verify that the estimated position has not drifted from the actual * position. By default the check is not performed. * The IRemoteControlDisplay must have been previously registered for this to have any effect. * @param rcd the IRemoteControlDisplay for which the anti-drift mechanism will be enabled * or disabled. Not null. * @param wantsSync if true, RemoteControlClient instances which expose their playback position * to the framework will regularly compare the estimated playback position with the actual * position, and will update the IRemoteControlDisplay implementation whenever a drift is * detected. */ public void remoteControlDisplayWantsPlaybackPositionSync(IRemoteControlDisplay rcd, boolean wantsSync) { synchronized(mRCStack) { boolean rcdRegistered = false; // store the information about this display // (display stack traversal order doesn't matter). final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next(); if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) { di.mWantsPositionSync = wantsSync; rcdRegistered = true; break; } } if (!rcdRegistered) { return; } // notify all current RemoteControlClients // (stack traversal order doesn't matter as we notify all RCCs) final Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator(); while (stackIterator.hasNext()) { final RemoteControlStackEntry rcse = stackIterator.next(); if (rcse.mRcClient != null) { try { rcse.mRcClient.setWantsSyncForDisplay(rcd, wantsSync); } catch (RemoteException e) { Log.e(TAG, "Error setting position sync flag for RCD on RCC: ", e); } } } } } public void setRemoteControlClientPlaybackPosition(int generationId, long timeMs) { // ignore position change requests if invalid generation ID synchronized(mRCStack) { Loading
media/java/android/media/IAudioService.aidl +14 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,20 @@ interface IAudioService { * display doesn't need to receive artwork. */ oneway void remoteControlDisplayUsesBitmapSize(in IRemoteControlDisplay rcd, int w, int h); /** * Controls whether a remote control display needs periodic checks of the RemoteControlClient * playback position to verify that the estimated position has not drifted from the actual * position. By default the check is not performed. * The IRemoteControlDisplay must have been previously registered for this to have any effect. * @param rcd the IRemoteControlDisplay for which the anti-drift mechanism will be enabled * or disabled. Not null. * @param wantsSync if true, RemoteControlClient instances which expose their playback position * to the framework will regularly compare the estimated playback position with the actual * position, and will update the IRemoteControlDisplay implementation whenever a drift is * detected. */ oneway void remoteControlDisplayWantsPlaybackPositionSync(in IRemoteControlDisplay rcd, boolean wantsSync); /** * Request the user of a RemoteControlClient to seek to the given playback position. * @param generationId the RemoteControlClient generation counter for which this request is Loading
media/java/android/media/IRemoteControlClient.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -47,5 +47,6 @@ oneway interface IRemoteControlClient void plugRemoteControlDisplay(IRemoteControlDisplay rcd, int w, int h); void unplugRemoteControlDisplay(IRemoteControlDisplay rcd); void setBitmapSizeForDisplay(IRemoteControlDisplay rcd, int w, int h); void setWantsSyncForDisplay(IRemoteControlDisplay rcd, boolean wantsSync); void seekTo(int clientGeneration, long timeMs); } No newline at end of file
media/java/android/media/RemoteControlClient.java +89 −22 Original line number Diff line number Diff line Loading @@ -645,12 +645,21 @@ public class RemoteControlClient sendAudioServiceNewPlaybackState_syncCacheLock(); // handle automatic playback position refreshes initiateCheckForDrift_syncCacheLock(); } } } private void initiateCheckForDrift_syncCacheLock() { if (mEventHandler == null) { return; } mEventHandler.removeMessages(MSG_POSITION_DRIFT_CHECK); if (timeInMs == PLAYBACK_POSITION_INVALID) { // this playback state refresh has no known playback position, it's no use if (!mNeedsPositionSync) { return; } if (mPlaybackPositionMs < 0) { // the current playback state has no known playback position, it's no use // trying to see if there is any drift at this point // (this also bypasses this mechanism for older apps that use the old // setPlaybackState(int) API) Loading @@ -660,20 +669,18 @@ public class RemoteControlClient // playback position moving, schedule next position drift check mEventHandler.sendMessageDelayed( mEventHandler.obtainMessage(MSG_POSITION_DRIFT_CHECK), getCheckPeriodFromSpeed(playbackSpeed)); } } getCheckPeriodFromSpeed(mPlaybackSpeed)); } } private void onPositionDriftCheck() { if (DEBUG) { Log.d(TAG, "onPositionDriftCheck()"); } synchronized(mCacheLock) { if ((mEventHandler == null) || (mPositionProvider == null)) { if ((mEventHandler == null) || (mPositionProvider == null) || !mNeedsPositionSync) { return; } if ((mPlaybackPositionMs == PLAYBACK_POSITION_INVALID) || (mPlaybackSpeed == 0.0f)) { if (DEBUG) { Log.d(TAG, " no position or 0 speed, no check needed"); } if ((mPlaybackPositionMs < 0) || (mPlaybackSpeed == 0.0f)) { if (DEBUG) { Log.d(TAG, " no valid position or 0 speed, no check needed"); } return; } long estPos = mPlaybackPositionMs + (long) Loading Loading @@ -1011,6 +1018,12 @@ public class RemoteControlClient */ private final PendingIntent mRcMediaIntent; /** * Reflects whether any "plugged in" IRemoteControlDisplay has mWantsPositonSync set to true. */ // TODO consider using a ref count for IRemoteControlDisplay requiring sync instead private boolean mNeedsPositionSync = false; /** * A class to encapsulate all the information about a remote control display. * A RemoteControlClient's metadata and state may be displayed on multiple IRemoteControlDisplay Loading @@ -1020,6 +1033,7 @@ public class RemoteControlClient private IRemoteControlDisplay mRcDisplay; private int mArtworkExpectedWidth; private int mArtworkExpectedHeight; private boolean mWantsPositionSync = false; DisplayInfoForClient(IRemoteControlDisplay rcd, int w, int h) { mRcDisplay = rcd; Loading Loading @@ -1109,6 +1123,14 @@ public class RemoteControlClient } } public void setWantsSyncForDisplay(IRemoteControlDisplay rcd, boolean wantsSync) { // only post messages, we can't block here if ((mEventHandler != null) && (rcd != null)) { mEventHandler.sendMessage(mEventHandler.obtainMessage( MSG_DISPLAY_WANTS_POS_SYNC, wantsSync ? 1 : 0, 0/*arg2 ignored*/, rcd)); } } public void seekTo(int generationId, long timeMs) { // only post messages, we can't block here if (mEventHandler != null) { Loading Loading @@ -1160,6 +1182,7 @@ public class RemoteControlClient private final static int MSG_UPDATE_DISPLAY_ARTWORK_SIZE = 9; private final static int MSG_SEEK_TO = 10; private final static int MSG_POSITION_DRIFT_CHECK = 11; private final static int MSG_DISPLAY_WANTS_POS_SYNC = 12; private class EventHandler extends Handler { public EventHandler(RemoteControlClient rcc, Looper looper) { Loading Loading @@ -1210,6 +1233,9 @@ public class RemoteControlClient case MSG_POSITION_DRIFT_CHECK: onPositionDriftCheck(); break; case MSG_DISPLAY_WANTS_POS_SYNC: onDisplayWantsSync((IRemoteControlDisplay)msg.obj, msg.arg1 == 1); break; default: Log.e(TAG, "Unknown event " + msg.what + " in RemoteControlClient handler"); } Loading Loading @@ -1410,13 +1436,29 @@ public class RemoteControlClient /** pre-condition rcd != null */ private void onUnplugDisplay(IRemoteControlDisplay rcd) { synchronized(mCacheLock) { final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) { displayIterator.remove(); return; break; } } // list of RCDs has changed, reevaluate whether position check is still needed boolean oldNeedsPositionSync = mNeedsPositionSync; boolean newNeedsPositionSync = false; displayIterator = mRcDisplays.iterator(); while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); if (di.mWantsPositionSync) { newNeedsPositionSync = true; break; } } mNeedsPositionSync = newNeedsPositionSync; if (oldNeedsPositionSync != mNeedsPositionSync) { // update needed? initiateCheckForDrift_syncCacheLock(); } } } Loading @@ -1440,6 +1482,31 @@ public class RemoteControlClient } } /** pre-condition rcd != null */ private void onDisplayWantsSync(IRemoteControlDisplay rcd, boolean wantsSync) { synchronized(mCacheLock) { boolean oldNeedsPositionSync = mNeedsPositionSync; boolean newNeedsPositionSync = false; final Iterator<DisplayInfoForClient> displayIterator = mRcDisplays.iterator(); // go through the list of RCDs and for each entry, check both whether this is the RCD // that gets upated, and whether the list has one entry that wants position sync while (displayIterator.hasNext()) { final DisplayInfoForClient di = (DisplayInfoForClient) displayIterator.next(); if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) { di.mWantsPositionSync = wantsSync; } if (di.mWantsPositionSync) { newNeedsPositionSync = true; } } mNeedsPositionSync = newNeedsPositionSync; if (oldNeedsPositionSync != mNeedsPositionSync) { // update needed? initiateCheckForDrift_syncCacheLock(); } } } private void onSeekTo(int generationId, long timeMs) { synchronized (mCacheLock) { if ((mCurrentClientGenId == generationId) && (mPositionUpdateListener != null)) { Loading