Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 13570129 authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

Remote volume handling in MediaRouter

Extend MediaRouter.UserRouteInfo to enable setting playback
 information, which includes volume. When the user route instance
 has a RemoteControlClient, forward any playback information to it.
 Enable specifying a callback to be notified of volume events
 on the route.
Extend MediaRouter.RouteInfo to enable retrieving playback
 information.

Update RemoteControlClient javadoc to reflect which parts of the
 API are not intended to be made public.

Change-Id: I59d728eb61747af6c8c89d53f0faeb07940594c3
parent fe54cb6f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -198,6 +198,7 @@ LOCAL_SRC_FILES += \
	media/java/android/media/IMediaScannerService.aidl \
	media/java/android/media/IRemoteControlClient.aidl \
	media/java/android/media/IRemoteControlDisplay.aidl \
	media/java/android/media/IRemoteVolumeObserver.aidl \
	media/java/android/media/IRingtonePlayer.aidl \
	telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl \
	telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
+0 −33
Original line number Diff line number Diff line
@@ -2152,19 +2152,6 @@ public class Intent implements Parcelable, Cloneable {
    public static final String ACTION_USB_AUDIO_DEVICE_PLUG =
            "android.intent.action.USB_AUDIO_DEVICE_PLUG";

    /**
     * @hide (to be un-hidden)
     * Broadcast Action: the volume handled by the receiver should be updated based on the
     * mutually exclusive extras, {@link #EXTRA_VOLUME_UPDATE_DIRECTION}
     * and {@link #EXTRA_VOLUME_UPDATE_VALUE}.
     *
     * @see #EXTRA_VOLUME_UPDATE_DIRECTION
     * @see #EXTRA_VOLUME_UPDATE_VALUE
     * @see android.media.RemoteControlClient
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_VOLUME_UPDATE = "android.intent.action.VOLUME_UPDATE";

    /**
     * <p>Broadcast Action: The user has switched on advanced settings in the settings app:</p>
     * <ul>
@@ -2854,26 +2841,6 @@ public class Intent implements Parcelable, Cloneable {
    public static final String EXTRA_USERID =
            "android.intent.extra.user_id";

    /**
     * @hide (to be un-hidden)
     * An integer indicating whether the volume is to be increased (positive value) or decreased
     * (negative value). For bundled changes, the absolute value indicates the number of changes
     * in the same direction, e.g. +3 corresponds to three "volume up" changes.
     * @see #ACTION_VOLUME_UPDATE
     */
    public static final String EXTRA_VOLUME_UPDATE_DIRECTION =
            "android.intent.extra.VOLUME_UPDATE_DIRECTION";

    /**
     * @hide (to be un-hidden)
     * An integer indicating the new volume value, always between 0 and the value set for
     * {@link RemoteControlClient#PLAYBACKINFO_VOLUME_MAX} with
     * {@link RemoteControlClient#setPlaybackInformation(int, int)}
     * @see #ACTION_VOLUME_UPDATE
     */
    public static final String EXTRA_VOLUME_UPDATE_VALUE =
            "android.intent.extra.VOLUME_UPDATE_VALUE";

    // ---------------------------------------------------------------------
    // ---------------------------------------------------------------------
    // Intent flags (see mFlags variable).
+35 −15
Original line number Diff line number Diff line
@@ -4243,6 +4243,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        public int mPlaybackVolumeHandling;
        public int mPlaybackStream;
        public int mPlaybackState;
        public IRemoteVolumeObserver mRemoteVolumeObs;

        public void resetPlaybackInfo() {
            mPlaybackType = RemoteControlClient.PLAYBACK_TYPE_LOCAL;
@@ -4251,6 +4252,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
            mPlaybackVolumeHandling = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME_HANDLING;
            mPlaybackStream = AudioManager.STREAM_MUSIC;
            mPlaybackState = RemoteControlClient.PLAYSTATE_STOPPED;
            mRemoteVolumeObs = null;
        }

        /** precondition: mediaIntent != null, eventReceiver != null */
@@ -4335,7 +4337,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
                        "  -- state: " + rcse.mPlaybackState +
                        "  -- vol handling: " + rcse.mPlaybackVolumeHandling +
                        "  -- vol: " + rcse.mPlaybackVolume +
                        "  -- volMax: " + rcse.mPlaybackVolumeMax);
                        "  -- volMax: " + rcse.mPlaybackVolumeMax +
                        "  -- volObs: " + rcse.mRemoteVolumeObs);
                
            }
        }
        synchronized (mMainRemote) {
@@ -5018,6 +5022,20 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
        }
    }

    // FIXME send a message instead of updating the stack synchronously
    public void registerRemoteVolumeObserverForRcc(int rccId, IRemoteVolumeObserver rvo) {
        synchronized(mRCStack) {
            Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
            while(stackIterator.hasNext()) {
                RemoteControlStackEntry rcse = stackIterator.next();
                if (rcse.mRccId == rccId) {
                    rcse.mRemoteVolumeObs = rvo;
                    break;
                }
            }
        }
    }

    /**
     * Checks if a remote client is active on the supplied stream type. Update the remote stream
     * volume state if found and playing
@@ -5100,23 +5118,24 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
            // only handling discrete events
            return;
        }
        String packageForRcc = null;
        IRemoteVolumeObserver rvo = null;
        synchronized (mRCStack) {
            Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
            while(stackIterator.hasNext()) {
                RemoteControlStackEntry rcse = stackIterator.next();
                //FIXME OPTIMIZE store this info in mMainRemote so we don't have to iterate?
                if (rcse.mRccId == rccId) {
                    packageForRcc = rcse.mReceiverComponent.getPackageName();
                    rvo = rcse.mRemoteVolumeObs;
                    break;
                }
            }
        }
        if (packageForRcc != null) {
            Intent intent = new Intent(Intent.ACTION_VOLUME_UPDATE);
            intent.putExtra(Intent.EXTRA_VOLUME_UPDATE_DIRECTION, direction);
            intent.setPackage(packageForRcc);
            mContext.sendBroadcast(intent);
        if (rvo != null) {
            try {
                rvo.dispatchRemoteVolumeUpdate(direction, -1);
            } catch (RemoteException e) {
                Log.e(TAG, "Error dispatching relative volume update", e);
            }
        }
    }

@@ -5147,23 +5166,24 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
            }
            rccId = mMainRemote.mRccId;
        }
        String packageForRcc = null;
        IRemoteVolumeObserver rvo = null;
        synchronized (mRCStack) {
            Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
            while(stackIterator.hasNext()) {
                RemoteControlStackEntry rcse = stackIterator.next();
                if (rcse.mRccId == rccId) {
                    //FIXME OPTIMIZE store this info in mMainRemote so we don't have to iterate?
                    packageForRcc = rcse.mReceiverComponent.getPackageName();
                    rvo = rcse.mRemoteVolumeObs;
                    break;
                }
            }
        }
        if (packageForRcc != null) {
            Intent intent = new Intent(Intent.ACTION_VOLUME_UPDATE);
            intent.putExtra(Intent.EXTRA_VOLUME_UPDATE_VALUE, vol);
            intent.setPackage(packageForRcc);
            mContext.sendBroadcast(intent);
        if (rvo != null) {
            try {
                rvo.dispatchRemoteVolumeUpdate(0, vol);
            } catch (RemoteException e) {
                Log.e(TAG, "Error dispatching absolute volume update", e);
            }
        }
    }

+2 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.media.IAudioFocusDispatcher;
import android.media.IAudioRoutesObserver;
import android.media.IRemoteControlClient;
import android.media.IRemoteControlDisplay;
import android.media.IRemoteVolumeObserver;
import android.media.IRingtonePlayer;
import android.net.Uri;
import android.view.KeyEvent;
@@ -135,6 +136,7 @@ interface IAudioService {
    oneway void setPlaybackInfoForRcc(int rccId, int what, int value);
           int  getRemoteStreamMaxVolume();
           int  getRemoteStreamVolume();
    oneway void registerRemoteVolumeObserverForRcc(int rccId, in IRemoteVolumeObserver rvo);

    void startBluetoothSco(IBinder cb);
    void stopBluetoothSco(IBinder cb);
+26 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.media;


/**
 * AIDL for the AudioService to report requests for remote volume update requests.
 * @hide
 */
oneway interface IRemoteVolumeObserver {
    void dispatchRemoteVolumeUpdate(int direction, int value);
}
Loading